Im having trouble to get the distinct sales from my DB, I tried INNER JOIN but it doesn't work. My SQL statement is something like this:
SELECT * FROM (SELECT DISTINCT(mta.Maintenance.userId) AS a
FROM mta.Maintenance WHERE 1=1) AS t
INNER JOIN mta.Maintenance
ON t.a = mta.Maintenance.userId
WHERE 1=1
AND mta.Maintenance.paymentStatus = 'PAID'
AND mta.Maintenance.createdAt < 1648771199000
AND mta.Maintenance.createdAt > 1640995199000
AND mta.Maintenance.deletedAt IS NULL
AND mta.Maintenance.price > 50
And the table is something like this:
a
maintenanceId
adminId
storeId
vehicleId
serviceId
paymentStatus
status
createdAt
userId
65
50
\N
6
26
38
PAID
PENDING
1644237405347
65
71
70
28
3
32
32
PAID
PENDING
1644499807732
71
71
72
52
3
34
30
PAID
PENDING
1644851796531
71
78
75
52
6
36
38
PAID
PENDING
1644858138158
78
78
76
52
6
37
91
PAID
PENDING
1644863060421
78
And I want:
a
maintenanceId
adminId
storeId
vehicleId
serviceId
paymentStatus
status
createdAt
userId
65
50
\N
6
26
38
PAID
PENDING
1644237405347
65
71
70
28
3
32
32
PAID
PENDING
1644499807732
71
78
75
52
6
36
38
PAID
PENDING
1644858138158
78
Basically the distincts results with the MIN(createdAt).
Thanks!!
Try using ROW_NUMBER() to group the rows by UserId and assign a sort number based on the CreatedAt value. Then grab rows where SortNum = 1
WITH cte AS (
SELECT *, ROW_NUMBER() OVER(PARTITION BY UserId ORDER BY CreatedAt ASC) AS SortNum
FROM Maintenance
)
SELECT *
FROM cte
WHERE RowNum = 1
a
maintenanceId
adminId
storeId
vehicleId
serviceId
paymentStatus
status
createdAt
userId
RowNum
65
50
N
6
26
38
PAID
PENDING
1644237405347
65
1
71
70
28
3
32
32
PAID
PENDING
1644499807732
71
1
78
75
52
6
36
38
PAID
PENDING
1644858138158
78
1
db<>fiddle here
Try using the MySQL IN Operator of MySQL and from there select the min(createdat) column and group them by a in the main query.
SELECT * FROM maintenance a
WHERE createdat
IN (SELECT MIN(createdat) FROM maintenance b WHERE b.a=a.a)
GROUP BY a;
RESULT
a maintenanceId adminId storeId vehicleId serviceId paymentStatus STATUS createdAt userId
------ ------------- ------- ------- --------- --------- ------------- ------- ------------- --------
65 50 (NULL) 6 26 38 PAID PENDING 1644237405347 65
71 70 28 3 32 32 PAID PENDING 1644499807732 71
78 75 52 6 36 38 PAID PENDING 1644858138158 78
Related
There are two campaigns running campaign A and Campaign B and list of user ids participated in those two campaign is given below. Calculate the number of users based on the below conditions by writing a single query.
Participated in campaign A
Participated in campaign B
Participated in campaign A only
Participated in campaign B only
Participated in both the campaigns
Participated in either campaign A or Campaign B
Campaign A Campaign B
user_id user_id
91 62
27 11
58 16
50 92
64 17
65 71
54 12
98 37
78 93
24 58
31 54
73 94
63 85
72 30
94 32
20 1
38 48
8 99
43 45
33 46
26 39
100 29
61 49
87 73
84 81
15 88
80 70
77 33
40 55
82
42
56
95
88
I am not able to figure out how to write in single SQL query.
Assuming you have two different tables, you can use union all and aggregation:
select in_a, in_b, count(*) as num_users
from ((select user_id, 1 as in_a, 0 as in_b
from a
) union all
(select user_id, 0 as in_a, 1 as in_b
from b
)
) u
group by in_a, in_b;
This gives you all the information you need. You can use group by in_a, in_b with rollup to get all combinations.
Or, you can summarize this into one row:
select sum(in_a) as in_a, sum(in_b) as in_b,
sum(in_a * (1 - in_b)) as in_a_only,
sum(in_b * (1 - in_a)) as in_b_only,
sum(in_a * in_b) as in_ab
from ((select user_id, 1 as in_a, 0 as in_b
from a
) union all
(select user_id, 0 as in_a, 1 as in_b
from b
)
) u;
Note: These both assume that users are unique in each campaign. If not, just use select distinct or union in the subquery.
In order to display data (orders or bids) in a excel-like grid, i fetch from my database with the help of this query. In this case, the order_bid table store the lines that compose an order (a line for each item), the item table defines the price of an item, the current sale the item is displayed on, and the lot table defines the item itself (name, description_ect...)
Here is the request i make, orders are another table but the important part is that an order_bid is linked to an order, and orders are linked to a unique sale, but it seems to ignore the WHERE close, so i get a lot more results than expected (for example if a client placed a bid for lot 4 of sale 1, i would see a bid for sale 2 lot 4, and so on for all sales that have a lot number 4 (so all of them basically))
SELECT o.id, o.order_id, o.lot_num, o.bid, i.lot_id, i.sale, i.price, l.description_fr
FROM order_bid o
INNER JOIN item i
ON o.lot_num = i.lot_num
INNER JOIN lot l
ON l.id = i.lot_id
WHERE o.order_id = 38
For example i expect for a request a result like:
id
order_id
lot_num
bid
lot_id
sale
price
description_fr
110
38
17
135
19
sale1
135
description1
111
38
21
83
23
sale1
183
description2
109
38
10
100
790
sale1
100
description3
but i get:
id
order_id
lot_num
bid
lot_id
sale
price
description_fr
110
38
17
135
19
sale1
135
description1
111
38
21
83
23
sale1
183
description2
111
38
21
183
11968
sale11
150
description4
109
38
10
100
790
sale1
100
description3
and a lot of other lots that i shouldn't be getting from other sales
and i verified, when i request all the order_bid with order_id = 38 (SELECT * FROM order_bid WHERE order_id = 38) i get:
id
order_id
lot_num
bid
109
38
10
100
110
38
17
135
111
38
21
183
summarized: i get info from multiple sales when i'm supposed to get only from one (done using the order_id filter)
discount table
category_id discount_amount
65 300
65 300
65 300
66 400
66 400
66 400
67 200
67 200
67 200
product table
product_id category_id
1 65
2 66
3 67
I want to fetch discount_amount according to category_id once no repetition
Give a try to below query:
SELECT DISTINCT product_id, p.category_id, sum(discount_amount)
FROM product p
INNER JOIN discount d ON p.category_id = d.category_id
GROUP BY product_id;
Output:
product_id, category_id, total discount amount
1 65 900
2 66 1200
3 67 600
I have following MySQL table structure,
id product_id filter_tag_id
14 1 48
17 3 49
18 10 49
19 10 54
20 11 49
21 11 55
22 12 49
23 12 56
24 9 48
25 9 52
26 6 48
27 6 53
28 7 48
29 7 56
30 8 48
31 8 53
32 13 48
33 13 52
34 14 48
35 14 54
36 14 55
37 15 48
38 15 55
i need to fetch only those product_id's which have same filter_tag_id's,
For example only one product_id (9 and 13) having the same filter_tag_id (48 and 52), so I need to fetch only product_id 9 and 13, I'm trying following query, but no success yet.
select product_id from filter_data where filter_tag_id=52 AND filter_tag_id=48;
select product_id from filter_data where filter_tag_id in (52,48);
First query return no result and second one returning wrong results
Use self-join. It looks like more complicated than GROUP BY, but it is faster than group-by. Because with GROUP BY approach, those which only has 48 or 52 should be groupped that is not unneeded rows.
SELECT t1.product_id
FROM filter_data t1 INNER JOIN filter_data t2 ON t1.product_id = t2.product_id
WHERE t1.filter_tag_id = 48 AND t2.filter_tag_id = 52;
If what you want is to find only product_ids having filter_tag_id values equal to 48 and 52 and nothing else but these two values, then try:
SELECT product_id
FROM mytable
GROUP BY product_id
HAVING COUNT(CASE WHEN filter_tag_id = 48 THEN 1 END) > 0 AND
COUNT(CASE WHEN filter_tag_id = 52 THEN 1 END) > 0 AND
COUNT(CASE WHEN filter_tag_id NOT IN (48,52) THEN 1 END) = 0
Demo here
use GROUP BY
Select product_id,COUNT(DISTINCT filter_tag_id) filter_match
from filter_data where filter_tag_id in (52,48)
GROUP BY product_id
HAVING filter_match = 2
the value of filter_match is count you will pass in condition
I have table data in this format
studno name level year term subject1 subject2 subject3
212 victor l1 2000 1 45 56 80
213 HOM l1 2000 1 42 56 70
214 ken l1 2000 1 60 70 50
215 ted l1 2000 1 46 36 47
212 victor l1 2000 2 45 36 68
213 Hom l1 2000 2 38 78 49
214 ken l1 2000 2 38 34 62
my desired output is the following
studno name level year term subject1 sub1rank subject2 sub2rank
213 victor l1 2000 1 42 3 56 2
214 HOM l1 2000 1 60 1 70 1
215 TED l1 2000 1 46 2 36 3
212 victor l1 2000 2 45 2 36 1
213 hOM l1 2000 2 38 3 36 1
214 KEN l1 2000 2 38 3 32 3
215 TED l1 2000 2 90 1 30 4
I have managed to get the rank but the problem is how to get the rank per year, level, term and subject. another problem is that if i use nested statement and try to create view in mysql database it throws an error, "View's SELECT contains a subquery in the FROM clause"
You can do this with correlated subqueries in the select clause. If I understand correctly, something like this:
select t.*,
(select COUNT(distinct t1.subject1)
from t t2
where t2.level = t.level and t2.year = t.year and t2.term = t.term and
t2.subject1 >= t.subject1
) as subj1rank,
(select COUNT(distinct t2.subject2)
from t t2
where t2.level = t.level and t2.year = t.year and t2.term = t.term and
t2.subject2 >= t.subject2
) as subj2rank
from t
The count(*) might be count(distinct subject1) (etc.), depending on how you treat ties.