Using 2 levels avobe column in union subquery - php

I have a very complicated query which involves a subquery and this subquery usas an union as the table. I want to use a column from the first level (a field before the subquery) as part of the where clausule in the union. Like this:
SELECT
type,
registered_number - (
SELECT
MAX(last)
FROM (
SELECT
MAX(b) as last
FROM
x
WHERE
a = type
UNION ALL
SELECT
MAX(b) as last
FROM
y
WHERE
a = type
) as last_table
) as last
FROM `x`;
Sample data
Table X
a
b
1
25
2
26
3
27
TABLE Y
a
b
1
25
2
24
3
31
TABLE s
id
type
registered_number
1
1
7
2
2
8
3
3
9
EXPECTED RESULT
type
last
1
18
2
18
3
22

I suggest doing a union of the x and y tables first, then join s to an aggregate of the union subquery.
SELECT s.type, t.b AS last
FROM s
INNER JOIN
(
SELECT a, MAX(b) AS b
FROM
(
SELECT a, b FROM x
UNION ALL
SELECT a, b FROM y
) t
GROUP BY a
) t
ON t.a = s.type
ORDER BY s.type;

Related

Find and remove MySQL row duplicates that are right after each other

I'm trying to find and remove MySQL row duplicates that are right after each other, instead of finding all, even if they're not straight after each other.
SELECT DISTINCT(content) AS contentMsg, COUNT(*) AS cnt, `ticketId`,`date`
FROM ticketsReplies
WHERE username = 'X'
GROUP BY contentMsg, ticketId
HAVING cnt > 1
ORDER BY cnt DESC
This is my current code. However, this finds duplicates if there's just two of the same answers in one ticket instead of them having to be IDs right after each other (which can happen if you send a POST request, and it fails, and you refresh etc).
How would I go about finding ones that are only 1 ID from each other.
So finding e.g. 1,2,3,4,5,6,7 instead of 1,3,9,11
E.g. if you have
ID EMAIL
---------------------- --------------------
1 aaa
2 bbb
3 bbb
4 bbb
5 ddd
6 eee
7 aaa
8 aaa
9 bbb
If you have this, it should find the following IDs:
2,3,4 but not 9 as it's not directly after 4 even though its a duplicate.
It should also find 7,8 but not 1 as they are not right after each other.
E.g.:
SELECT id
FROM
( SELECT x.id FROM my_table x JOIN my_table y ON y.email = x.email AND y.id = x.id + 1 ) a
UNION
( SELECT y.id FROM my_table x JOIN my_table y ON y.email = x.email AND y.id = x.id + 1 );
If there are gaps in your id list (eg 5, 6, 9, 11), simply comparing id = id+1 wouldn't work. The solution I came up with is to create two identical temporary tables with sequential row-numbers. In that case you can safely compare the rows based on their number, even if the id's have gaps.
DELETE FROM tab WHERE id IN (
SELECT A.id
FROM
(
SELECT row_nr, id, email FROM (
SELECT
(#cnt1 := #cnt1 + 1) AS row_nr,
t.id,t.email
FROM tab AS t
CROSS JOIN (SELECT #cnt1 := 0) AS d
ORDER BY t.id
) x
) A
INNER JOIN
(
SELECT row_nr, id, email FROM (
SELECT
(#cnt2 := #cnt2 + 1) AS row_nr,
t.id,t.email
FROM tab AS t
CROSS JOIN (SELECT #cnt2 := 0) AS d
ORDER BY t.id
) x
) B
ON A.row_nr-1 = B.row_nr AND A.email=B.email
)
The two (SELECT row_nr, id, email FROM ... ) x parts create two identical tables A and B like
row_nr id email
1 1 aaa
2 4 aaa
3 5 bbb
4 9 aaa
5 11 aaa
Then you can compare the sequential row-nr's and email:
ON A.row_nr-1 = B.row_nr AND A.email=B.email
Selecting the result-id's gives you the id's 4, 11 which are the duplicates. Then you can delete those id's:
DELETE FROM tab WHERE id IN ( ... )
Here is a Fiddle to test the SELECT part.
NOTE: Before you try this at home, please backup your table!

I want to sort my CatId in this order 1 2 3 4 1 2 3 4 but there is a catch that it first check allocationId last 14 digits if catid is same

My query is this:-
SELECT m.allocationID,mt.CatId,mt.CatSName
FROM msttransaction m,msttemp mt WHERE m.isPending='Y'
AND m.allocationID IN (
SELECT mt.AllocationId FROM msttemp WHERE mt.quarterId='010100001'
) ORDER BY SUBSTRING(m.AllocationId, -14)
output:-
12980013120170919125006 1 A
12980013320170919125404 3 C
12980013420170919125603 4 D
12980013820170919130113 2 B
12980013920170919130315 3 C
12980014020170919130519 4 D
12980013220170919130613 2 B
12980013720170919130722 1 A
In 129800 series last 14 digits is date and time. First I have to sort my output according to 1 2 3 4 1 2 3 4 but first it check last 14 digits of 129800 of same catId that comes first which comes first.
Expected output
12980013120170919125006 1 A
12980013820170919130113 2 B
12980013320170919125404 3 C
12980013420170919125603 4 D
12980013720170919130722 1 A
12980013220170919130613 2 B
12980013920170919130315 3 C
12980014020170919130519 4 D
Does this do it?
ORDER BY m.CatId, SUBSTRING(m.AllocationId, -14)
The point is to order first by that CatId, then order by the embedded datastamp in the AllocationId.
If it were me I'd be more formal about the datestamp ordering, by formally extracting it from your strings using STR_TO_DATE() like this. This isn't strictly necessary, but good practice anyhow.
ORDER BY m.CatId, STR_TO_DATE(SUBSTRING(m.AllocationId, -14), '%Y%m%d%H%i%s'))
Plus, then you could use date manipulation like
ORDER BY m.CatId, LAST_DAY(STR_TO_DATE(SUBSTRING(m.AllocationId, -14), '%Y%m%d%H%i%s')))
to gather all the datestamps in a month together for ordering, or some such thing.
Here's an example: http://sqlfiddle.com/#!9/1c87ee/6/0
You can introduce a variable that will give you the order of the CatId when the result set would have been ordered by CatId and then the 14 last digits of the AllocationId. So in your example this variable would be either 1 or 2.
Once you have that variable value for each record, you can sort by that value first, and then by CatId:
select t.allocationId, CatId
from (
select t.*,
#rn := if(#CatId = CatId, #rn+1, if(#CatId := CatId, 1, 1)) rn
from (
SELECT m.allocationID, mt.CatId,mt.CatSName
FROM msttransaction m,
INNER JOIN msttemp mt
ON m.allocationID = mt.AllocationId
WHERE m.isPending='Y'
AND mt.quarterId='010100001'
ORDER BY CatId, SUBSTRING(m.AllocationId, -14)
) t,
(select #CatId := -1, #rn := -1) init
) t
order by rn, CatId;

Mysql Where Column A = X and Column B = Y and or Column B = Z

I'm trying to get a set of values from a pivot table where column A is equal to an array of values, so for example ID 12 has attribute_value_id equal to 3 and 9. Can this be done? I've got this far...
ID | post_id | attribute_id | attribute_value_id
8 12 1 3
9 12 2 13
10 13 1 3
11 13 2 9
12 16 1 3
13 16 2 9
88 11 1 1
89 11 2 8
90 11 3 18
91 11 4 22
The query...
select *
from `searching_for_posts`
where (
select count(*)
from `attributes`
inner join `searching_for_attributes`
on `attributes`.`id` = `searching_for_attributes`.`attribute_id`
where `searching_for_attributes`.`searching_for_post_id` = `searching_for_posts`.`id`
and (`attribute_value_id` = 3 and `attribute_value_id` = 9)
) >= 1
If I use the and then I get no values. If I use the or then I get 3 values but it should return 2. I have limited SQL experience.
You can do this using group by and having. Your logic is hard to follow, but it is something like this:
select post_id
from table t
where attribute_value_id in (3, 9)
group by post_id
having count(distinct attribute_id) = 2;
I would think you would want to check on attribute_id as well, but that doesn't seem to be part of the question.
EDIT:
If these are stored in another table:
select a.post_id
from attributes a join
searching_for_attributes sfa
on a.attribute_id = sfa.attribute_id and
a.attribute_value_id = sfa.attribute_value_id
group by a.post_id
having count(*) = (select count(*) from searching_for_attributes);
In response to #GordonLinoff answer, I've managed to use GROUP BY and HAVING COUNT to get the desired data. Here's what I came up with and hope this helps someone else...
select *
from `searching_for_posts`
where (
select count(*)
from `attributes`
inner join `searching_for_attributes` on `attributes`.`id` = `searching_for_attributes`.`attribute_id`
where `searching_for_attributes`.`searching_for_post_id` = `searching_for_posts`.`id`
and `attribute_value_id` in (3, 9)
having count(distinct `attributes`.`id`) = 2
) >= 1
group by `id`

MySql Distinct with multiple fields

I have 4 columns a, b c, d in my table (MySQL database) . I want to select the distinct values of ALL of these 4 columns in my table . More deeply my table is given bellow..
a b c d
--------------------------
1 3 3 4
1 2 3 0
1 1 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
In the above table (1,2,3,4) value are repeating 4 times(look the last 4 rows of my table). I want only the distinct one , ie i want to get the bellow table after mysql query..
a b c d
---------------
1 3 3 4
1 2 3 0
1 1 3 4
1 2 3 4
I think you guys got some idea . Im not familier with MySql .
select distinct a,b,c,d from your_table
SELECT DISTINCT column_name,column_name FROM table_name;
I mean
select distinct a,b,c,d from table_name;
Here is the link of w3schools
use :
SELECT DISTINCT * FROM yourtable
try this:
SELECT DISTINCT a FROM my_table
UNION
SELECT DISTINCT b FROM my_table
UNION
SELECT DISTINCT c FROM my_table
UNION
SELECT DISTINCT d FROM my_table
update 1:
SELECT a,b,c,d
FROM my_table
GROUP BY a,b,c,d;
http://sqlfiddle.com/#!2/c49ad/11

Merge results from two different tables with different column number, ORDER them by same key

I have two tables:
Table A: ID Cars Planes Num
1 3 5 2
2 8 44 1
3 7 23 6
4 6 2 7
Table B: ID Horses Dogs Cats Elefants Num
1 3 5 2 3 3
2 8 44 1 22 4
3 7 23 4 14 8
4 6 2 3 15 5
What I need to do: I need to get all results from both tables and sort them by the "Num" Column, where the "number" actually is unique for each result from both rows.
Is it even possible to "merge" those two tables and order them by "num" or should I just get each table separately ordered and do two loops checking always for the next num jumping between tables?
Thanks
you can merge them like that with UNION .
try this:
select num from(
select num from table1
union all
select num from table2
)t
order by num asc
DEMO HERE
EDIT:
select id ,Cars,Planes, Horses,Dogs,Cats,Elefants,num from(
select id ,Cars,Planes,'No horses' Horses,'No dogs' Dogs,'No cats' Cats,'No elefants' Elefants,num from table1
union all
select id,'No cars' Cars,'No planes' Planes,Horses,dogs,Cats,Elefants, num from table2
)t
order by num asc;
DEmo with other columns
SELECT NUM FROM TABLEA
UNION ALL
SELECT NUM FROM TABLEB
ORDER BY 1

Categories