Return rows that have every kind of instances that appear in a table for a given attribute - sql

E.g, given the schema:
account(id, type, cname)
I want to return the cnames of customers with every type of account that appears in account.
The following query will do:
SELECT cname, type
FROM account AS cust_account
WHERE NOT EXISTS (
SELECT type
FROM account
EXCEPT
SELECT type
FROM account
WHERE account.cname = cust_account.cname
);
However, I'm having trouble understanding the logic behind it. In particular, I don't see what's going on with the EXCEPT statement. Can anybody clarify this? Thank you.

As the WHERE NOT EXIST clause processes each record, it runs the following steps for the customer in that record. If it sees an empty list from step #3 it will include the customer in the query results (NOT EXISTS) .
Make a list of all the possible account types.
Make list of all accounts types that THIS customer has.
Subtract the list in step #2 from the list in step #1. This will create a list of any account types that THIS customer does NOT have. This will be empty for customers that have all accounts.
To be clear, since the WHERE NOT EXIST clause contains a correlated-sub query, steps 1-3 (which are performed by the sub query) are run one time for EACH row in the account table. For example, if the accounts table contains 100,000, the sub query will be run 100,000 times.

Related

How to use loop to find related object using Pentaho Data Integration

I want to identify the bad/invalid records so that i can add in a separate SQL Table. For example, we have an account object. And i want to find bad accounts. But i need to apply some filters on contact object. If conditions satisfy based on contact then i want to inserts those invalid account records in SQL Table.
I don't want to directly query from contact. I want to query using account but conditions should be used from contact.
Do anyone knows what is the best way to perform loop in Pentaho? Check each record for contact , if all contact's condition satisfy then add Account id in table. If one of the contact record doesn't satisfy condition. The relevant account should not be added in SQL Table
For Example:
On Account "A" we have 10 contacts
if the email field is empty on all 10 contacts then add Account in SQL table(As bad data)
if on two of contact rcords has email field populated but 8 of them are blank then Account id shouldn't be added in SQL table
How we can better implement this scenario using Pentaho? Any help matters
Thanks
So you can create a transformation similar to this:
You have a query with the different account contacts
Order the query data by account
Group the information by accounts and calculate the maximum ContactMail (so if all mails in contacts are null, the max will be a null, is the result of that step is shown in the Preview data part of my screenshot)
Filter rows by MaxContactMail IS NOT NULL
These could be the basic steps, you'll need to add more steps or perform more than one transformation depending on the complexity of your data.

SQL Database "Operation must use an updateable query" Workaround

So my basic goal is to create a database for a shopsystem, which is my task to do for my IT course. I tried to create a UPDATE-Query, that collects all the Sale Positions ("tblPosition.PositionAnzahl") ordered with a SELECT-Query and groups it by the products ordered, to have an overview about how often each product has been sold.
I want to do this to keep track of how many items are still left in the inventory.
The Query was supposed to update 1 field ("tblArtikel.ArtikelVerkauft") in my table "tblArtikel", in which all my articles and their information is stored.
However, i just found out that you cannot run UPDATE-Queries, that use SELECT-Query data, as i get a error, that says "Operation must use an updateable query".
This is the code i used for the query:
UPDATE tblArtikel as a JOIN
(SELECT p.PositionArtikelID, Sum(p.PositionAnzahl) AS SumOfPositionAnzahl
FROM tblPositionen as p
GROUP BY p.PositionArtikelID
) p
ON a.ArtikelID = p.PositionArtikelID
SET ArtikelVerkauft = p.SumOfPositionAnzahl;
Is there another way to keep track of all the Items left in my inventory, apart from doing what i did?
Here are screenshots of the 2 tables (the depending fields are circled red):
tblPositionen with field PositionAnzahl
tblArtikel with field ArtikelVerkauft
I have not worked with SQL before and only learned about it during 45 min, so ther emight be an easy way for this, but i would still appreciate every answer from you guys.

Querying via a form with value from textbox as criteria

The situation: metadata about biological specimens are collected in an Access table. The specimens come from human patients and patient data are collected in a separate table. To limit the amount of private health information we have hanging around, the patient database must be updated with new patients only when we actually receive samples from them.
So that the data entry workers know when they need to update the patient table, I want a button in the specimen data entry form that will pass an entered patient id value as criteria to a query.
The query looks like this right now:
SELECT Patients.[Patient id]
FROM Patients
WHERE (((Patients.[Patient id])=[Forms]![Specimen entry]![patient id]));
but it never has results, even when I run it from records that I know correspond to patients in the patient table. How do I fix this?
Suggestions about what to call this situation so that I can make better searches about it would also be appreciated. I'm an Access novice.
The query looks correct, but make sure the WHERE clause is comparing numbers to numbers or strings to strings (not a number to a string). Also confirm that the form and textbox names are correct. A quick test using your query worked for me.
Depending on how you plan to present the information, you can also dynamically create the query in VBA and then pass the information to the form.
For searching, I'd recommend some combination of access, dynamic, query, and vba.
alternative option
If you're only looking to see if a single patient exists in the table, it may be simpler to use the dlookup function:
If IsNull(DLookup("[Patient ID]", "Patients", "[Patient ID]='" & Me.Patient_ID & "'")) Then MsgBox "does not exist"
This will check to see if the patient exists (return a number) or does not exist (returns NULL).
https://support.office.com/en-us/article/DLookup-Function-8896cb03-e31f-45d1-86db-bed10dca5937

Return first 'unsorted' join in Oracle SQL

I have a table 'ACCOUNTS', with fields ACCTNO and ACPARENT. One account can be the parent of another. One account can have many children.
It's been discovered that certain external processes are using the 'first child' in certain reports and outputs - but there's no actual 'reason' for any particular child to be 'first', just an unintended bug in the code.
First step in untangling this - I need a query, that can be re-run (but not often, so optimisation is not really a factor) that will identify, for all accounts that are parents, what their 'first child' is.
Problem - the 'first child' isn't necessarily anything to do with record ID. If I run the following query, for example:
SELECT ACCTNO FROM ACCOUNTS WHERE ACPARENT = '80005217';
I get a result of:
ACCTNO
______
80007325
80007310
80007315
80007298
I can absolutely, 100% confirm that for this particular example, account 80007325 is the account ID being used as the 'first child'.
On the flipside, if I run a naive query of:
SELECT A1.ACCTNO, A2.ACCTNO AS CHILDACCOUNT FROM ACCOUNTS A1
INNER JOIN ACCOUNTS A2 ON A1.ACCTNO = A2.ACPARENT
WHERE A1.ACCTNO IN
(SELECT ACPARENT FROM ACCOUNTS);
then if I scroll down to where 80005217 is the parent account, I see the following list:
CHILDACCOUNT
______
80007298
80007310
80007315
80007325
It's sorted, even though it's exactly not what I want.
Is there a query that will get me a list of what I want in a single query? A list of all parent accounts, and their 'first child' as returned by SQL unsorted?
To guarantee records coming in a fixed order we must provide the database with sort criteria in the ORDER BY clause. If there is no attribute which defines "first-ness" then no guarantee is possible. Without an ORDER BY clause the records are essentially in an uncontrolled order, although because of
database internals they often fall into some kind of pattern.
So, what makes account 80007325 the first child WHERE ACPARENT = '80005217'? Clearly not numerical order. Is there some other criterion? Date created? A flag column? Seems like you need to talk to your users. Do they really care which records come first? All the time or just in some specific report?
If your users cannot specify the criteria there's not much you can do...
...although I might be tempted to sort CHILDACCOUNT numerically by ACCTNO whenever it is displayed. At least that would provide consistency, and the users will get used to it.

How to group records where a subset matches a condition

I have created a Microsoft report in VS2008 that displays details of products that are tested in a factory. Relevant fields to this problem are: SerialNumber (int), Pass (bool).
There is also a record ID which means several entries may exist per SerialNumber.
What we would like the report to show is to be grouped where SerialNumbers have never met the condition Pass=True (i.e. actual rejects) and the rest under where at least one record shows Pass=True.
The expression for the grouping currently is "=Fields!Pass.Value" which splits pass and fail records (and are then sorted etc).
In case anyone else comes up against this and wants to know how I solved it, I added an extra boolean column to the SQL query called 'Reject' which returns true or false and used this to group the report.
As powerful as the reporting can be, it just appears to be quite limited on what it can do with set data beyond Count, CountDistinct etc.