Query to extract data based on one column value - mysql

There are 2 tables that are supposed to have unique product codes but I came across a case where the product code ended up the same for two of the records in another table. I would like to get the product information based on the latest product year. Let's assume I have the following tables.
Table 1:
recall
id
product_year
product_code
yes
200
2019
3222333
no
201
2020
3222333
yes
202
2021
4332233
no
203
2021
5446553
yes
204
2018
6556677
Table 2:
recall
id
product_year
product_code
no
100
2019
2245643
yes
101
2020
1234543
no
102
2017
4332233
yes
103
2022
5446553
yes
104
2018
3344566
Table 3 contains only unique product code information and other updated information based on the latest product year. For eg: product code 3222333 has only one entry even though Table 1 has 2 entries for 3222333. But the problem comes for codes 4332233 and 5446553 which are present in both Table 1 and Table 2.
Table 3:
country
id
product_code
Brazil
301
3222333
Indonesia
302
4332233
Argentina
303
6556677
Chile
304
2245643
Brazil
305
1234543
Chile
306
5446553
USA
307
3344566
It is known that Table 3 doesn't contain correct data. But I would like to generate a query in mysql to get all the product codes from Table 3 and get the product code related information based on the latest product year. Earlier I was using something like COALESCE(table1.recall, table2.recall, null) assuming that only one value will be present and it works. But for the codes 4332233 and 5446553, it will always pick table 1 column value as recall values for the same product codes are present in both tables 1 and 2. How should I deal with this problem so that I get the data only based on the latest product year?
Expected output:
country
product_code
recall
Brazil
3222333
no
Indonesia
4332233
yes
Argentina
6556677
yes
Chile
2245643
no
Brazil
1234543
yes
Chile
5446553
yes
USA
3344566
yes

It did take me some time to realise how convenient it is to use UNION in this case. Below is the code written and tested in workbench.Please note this is currently the best answer I can come up with based on the limited table structure and sample data you provided. Since you say that it's possible for the same product_code to have the same product_year in both table1 and table2 and you have other means to determine the latest one, please tweak the code as you see fit. Hope this helps solve your issue.
select country, recall,ta.product_code as product_code
from
(select product_code,product_year,recall
from table1 t1
union
select product_code,product_year,recall
from table2 t2
) ta
join
(select product_code p_c,max(product_year) mx_y
from
(select product_code,product_year
from table1 t1
union
select product_code,product_year
from table2 t2
) t_union
group by product_code
) tb
on ta.product_code=p_c and ta.product_year=mx_y
join table3 t3
on p_c=t3.product_code
;

Related

Is it possible to write an SQL query that returns the values of something that doesn't exist in another table?

I'm trying to write an SQL query that returns the rows of a table in which certain data of a column does not appear in another table.
For example, let's say I have two tables:
Table 1:
Date Name Room
2020/01/23 John 201
2020/01/22 Rebecca 203
2020/01/22 Ronald 204
2020/01/22 Jimmy 205
Table 2 (does NOT have the same amount of columns):
Date Room
2020/01/22 203
2020/01/23 201
2020/01/22 202
2020/01/22 209
I want to find all the rows in Table 2 in which the room number does NOT show in table 1. Which means my SQL would return
2020/01/22 202
2020/01/22 209
Since room 202 and room 209 does not appear in Table 1.
How would I do this?
Use not exists:
select t2.*
from table2 t2
where not exists (select 1
from table1 t1
where t2.room = t1.room
);

Exclude the combination of 2 columns only from my query

Sounds simple but I couldn't find the solution for it.
I have a table with 3 columns. Account, Amount, Date.
I want to get all entries except the ones of one specific account with negative amount. But I still want to get the entries of this account if amount value is positive.
So with this query I'm also not getting the entries from account1 with a positive amount.
select * from table where (account!='account1' AND amount<='0') AND date='2020-05-01'
You can do this using WHERE NOT in your statement.
Example schema:
Account Amount Date
=====================================
1 Ben 200 2020-10-10
2 Frank 200 2020-10-10
3 Ben -300 2020-10-12
4 Ben 10 2020-10-16
5 Mary 2000 2020-10-16
6 Frank -200 2020-10-18
7 Ben -10 2020-10-18
8 Ben 0 2020-10-20
Now if you build your query like this
SELECT * FROM t1 WHERE NOT (account='Ben' AND amount<0);
you should get what you want (all records except the 3rd and 7th).
Edit: if you really only want to exclude records with negative amounts, you need to do < rather than <= as you did in your example above. Depends on whether you want row 8 to be included in the result or not.

MYSQL query - cross tab? Union? Join? Select? What should I be looking for?

Not sure what exactly it is I should be looking for, so I'm reaching out for help.
I have two tables that through queries I need to spit out one. the two tables are as follows:
Transactions:
TransactionID SiteID EmployeeName
520 2 Michael
521 3 Gene
TransactionResponse:
TransactionID PromptMessage Response PromptID
520 Enter Odometer 4500 14
520 Enter Vehicle ID 345 13
521 Enter Odometer 5427 14
521 Enter Vehicle ID 346 13
But what I need is the following, let's call it TransactionSummary:
TransactionID SiteID EmployeeName 'Odometer' 'VehicleID'
520 2 Michael 4500 345
521 3 Gene 5427 346
The "PromptID" column is the number version of "PromptMessage" so I could query off that if it's easier.
A good direction for what this query would be called is the least I'm hoping for. True extra credit for working examples or even using this provided example would be awesome!
For a predefined number of possible PromptID values you can use something like the following query:
SELECT t.TransactionID, t.SiteID, t.EmployeeName,
MAX(CASE WHEN PromptID = 13 THEN Response END) AS 'VehicleID',
MAX(CASE WHEN PromptID = 14 THEN Response END) AS 'Odometer'
FROM Transactions AS t
LEFT JOIN TransactionResponse AS tr
ON t.TransactionID = tr.TransactionID AND t.SiteID = tr.SiteID
GROUP BY t.TransactionID, t.SiteID, t.EmployeeName
The above query uses what is called conditional aggregation: a CASE expression is used within an aggregate function, so as to conditionally account for a subset of records within a group.

Distinct is not working in crystal reports and in mysql

id_no doc_id item_no product customer
123 2 1 A Daisy
123 2 9 A Ben
123 4 3 A Daisy
123 4 4 A Ben
123 6 11 B Daisy
123 6 13 B Ben
when I put it in my report it results to
Daisy Daisy
Ben
And it is also the result in mysql
select distinct customer from receipt where id_no like '123'
result:
Daisy
Daisy
Ben
Another query that I tried:
select distinct id_no, customer, product from receipt where id_no like '123'
result:
123 Daisy A
123 Daisy B
123 Daisy A
123 Ben A
123 Ben B
desired result:
Daisy
Ben
Please help me please.
Thank you guys for the help I found out why the other one keeps on showing. It is because the other Daisy is spelled as Daissy that's why.
Most likely your Customer name contains additional characters between the two records. Depending on how the datatype is implemented, spaces could matter and have contributed to the difference.
Try concatenating a character before and after customer.
I am unfamiliar with the concepts in Crystal Reports, but from what I understand, you would have to create a formula like so:
"XXX" & {Receipt.Customer} & "XXX"
If you run it again, you might recognize there is additional space like so:
XXXDaisyXXX
XXXDaisy XXX
^____ Additional Space
There is no chance of error while you using distinct ..it should return distinct value ...any way you can try another way
SELECT customer FROM receipt WHERE id_no like '123' GROUP BY customer
I don't see why you are fetching three records. I tried implementing your database and ran your query. It returned the result as expected.
See the above pic. There may be some issue with the data type you used. You may try grouping via customer, but I don't think it should affect your result anyway.
Also Check if the data types match.
The selection you made from customer id and id_no is unique and with distinct it should return only two rows
plase try this code
i get solution
select distinct `customer` from receipt where `id_no`='123'
this is right
i tryied this is my past project
best of luck

Select distinct user_id from a table for each request type

I have a table with 4 columns:
ID, USER_ID, SOURCE, CREATED_DATE
In that table is the following data:
ID USER_ID SOURCE CREATED_DATE
1 25 PURCHASE 2012-01-01 12:30:00
2 26 PLEDGE 2012-01-01 12:40:00
3 25 PLEDGE 2012-01-01 12:50:00
4 25 PURCHASE 2012-01-14 12:00:00
Now as you can see, I have 4 rows of data, and two unique users. User (25) made 3 transactions (two purchases and one pledge), user (26) made one transaction – (one pledge)
Here is what I am trying to achieve:
I need to select ALL transactions from this table, but I want to select a UNIQUE user for each REQUEST TYPE (source), and that row needs to be the EARLIEST TRANSACTION.
My expected result data would be:
ID USER_ID SOURCE CREATED_DATE
1 25 PURCHASE 2012-01-01 12:30:00
2 26 PLEDGE 2012-01-01 12:40:00
3 25 PLEDGE 2012-01-01 12:00:00
User (25) made TWO PURCHASES (one on 2012-01-01 and one on 2012-01-14) – the first is the one that gets returned.
This is the SQL I have come up with so far:
SELECT
Supporter.user_id,
MIN(Supporter.created) as created,
Supporter.*,
Supporter.source
FROM
supporters AS Supporter
GROUP BY Supporter.source
ORDER BY Supporter.created ASC
Now, this gets me really close, except it only selects ONE of the user id’s (the one with two items – a pledge and a purchase). If I could figure out how to select the data on both users, that would be what I need to do! Can anyone see what I am possibly doing wrong here, or missing?
You need to group by source and by user id
Something like this
SELECT
Supporter.user_id,
MIN(Supporter.created) as created,
Supporter.*,
Supporter.source
FROM
supporters AS Supporter
GROUP BY Supporter.user_id, Supporter.source
ORDER BY Supporter.created ASC