Data to display from 2 different table - mysql

I have 2 different tables in my database.
For eg; In table 1, named table1 , it has the following data:
||===============================||
|| ID | DATE ||
===================================
|| 1 | 2nd Jan ||
===================================
|| 2 | 4th Apr ||
===================================
And lets say in table 2, named table2, it has the following data:
||===============================||
|| ID | NAME ||
===================================
|| 1 | John ||
===================================
|| 2 | Pam ||
===================================
Now, both these table's (ID) is NOT THE SAME.
What I want to display is:
||===============================||===============================||
|| ID | NAME || ID | DATE ||
====================================================================
|| 1 | John || NULL | NULL ||
====================================================================
|| 2 | Pam || NULL | NULL ||
====================================================================
|| NULL | NULL || 1 | 2nd Jan ||
====================================================================
|| NULL | NULL || 2 | 4th Apr ||
====================================================================
So what I tried these mySQL statements:
select a.id, a.date, b.id, b.name from table1 a, table2 b
But this doesn't give me the correct display, it combines the result.
I also tried left join, it also combines the results.
What am I doing wrong? Please help me.
Thanks for reading.

select a.id, a.date, NULL id, NULL name from table1 a
UNION ALL
select NULL id, NULL date, b.id, b.name from table2 b
Just try above code.
Hope this will helps.

You can accomplish that with a 'fake' outer join:
select a.id, a.date, b.id, b.name
from table1 a
full outer join
table2 b
on 1 = 0;

Related

MySql query to check row_1 of column_1 is in between the row_1 and row_2 of column2

In the below table, I want to check the following using mysql query.
Any row_x of c1 is in between the row_x and row_x+1 of c2? So the result for the below table should be 2. Because 2 in c1 is in between 1 and 3 of c2
C1 || C2 ||
---------------
2 || 1 ||
5 || 3 ||
6 || 4 ||
7 || 5 ||
You can use math in the WHERE clause so:
select * from table where c1 between c2 and (c2 + 1)
should work.
https://www.db-fiddle.com/f/hE2oswGaEcJe9h8ZSdjURV/0

Join the table with incremental data of the same table

I am trying to implement a logic in Redshift Spectrum where my original table looks like below:
Records in the student table:
1 || student1 || Boston || 2019-01-01
2 || student2 || New York || 2019-02-01
3 || student3 || Chicago || 2019-03-01
1 || student1 || Dallas || 2019-03-01
Records in the incremental table studentinc looks like below:
1 || student1 || SFO || 2019-04-01
4 || student4 || Detroit || 2019-04-01
By joining both student and studentinc tables, I am trying to get the latest set of records which should look like below:
2 || student2 || New York || 2019-02-01
3 || student3 || Chicago || 2019-03-01
1 || student1 || SFO || 2019-04-01
4 || student4 || Detroit || 2019-04-01
I have got this solution by doing UNION of both student and studentinc, then querying the result of union based on max(modified_ts). However, this solution isn't good for huge tables, is there a better solution which works by joining both the tables?
1. Using Spark-SQL you can achieve this by using not in and union
scala> var df1 = Seq((1 ,"student1","Boston " , "2019-01-01" ),(2 ,"student2","New York" , "2019-02-01"),(3 ,"student3","Chicago " , "2019-03-01" ),(1 ,"student1","Dallas " , "2019-03-01")).toDF("id","name","country","_date")
register as temp table
scala> df1.registerTempTable("temp1")
scala> sql("select * from temp1") .show
+---+--------+--------+----------+
| id| name| country| _date|
+---+--------+--------+----------+
| 1|student1|Boston |2019-01-01|
| 2|student2|New York|2019-02-01|
| 3|student3|Chicago |2019-03-01|
| 1|student1|Dallas |2019-03-01|
+---+--------+--------+----------+
2nd DataFrame
scala> var df3 = Seq((1 , "student1", "SFO", "2019-04-01"),(4 , "student4", "Detroit", "2019-04-01")).toDF("id","name","country","_date")
scala> df3.show
+---+--------+-------+----------+
| id| name|country| _date|
+---+--------+-------+----------+
| 1|student1| SFO|2019-04-01|
| 4|student4|Detroit|2019-04-01|
+---+--------+-------+----------+
performing not in with union clause
scala> sql("select * from (select * from temp1 where id not in (select id from temp2 ) )tt") .union(df3).show
+---+--------+--------+----------+
| id| name| country| _date|
+---+--------+--------+----------+
| 2|student2|New York|2019-02-01|
| 3|student3|Chicago |2019-03-01|
| 1|student1| SFO|2019-04-01|
| 4|student4| Detroit|2019-04-01|
+---+--------+--------+----------+
2nd using Spark Dataframe this is faster than IN query becoz IN performs a row-wise operation.
scala> df1.join(df3,Seq("id"),"left_anti").union (df3).show
+---+--------+--------+----------+
| id| name| country| _date|
+---+--------+--------+----------+
| 2|student2|New York|2019-02-01|
| 3|student3|Chicago |2019-03-01|
| 1|student1| SFO|2019-04-01|
| 4|student4| Detroit|2019-04-01|
+---+--------+--------+----------+
Hope it helps you. let me know if you have any query related to the same
I would recommend window functions:
select s.*
from (select s.*,
row_number() over (partition by studentid order by date desc) as seqnum
from ((select s.* from student
) union all
(select i.* from incremental
from incremental
)
) s
) s
where seqnum = 1;
Note: The union all requires that the columns be exactly the same and in the same order. You may need to list out the columns if they are not the same.

How to increment counts of one table by getting counts from another table using update in mysql?

I have two tables
one is business_details
+--------------+--------------++--------------+
| msisdn | total_counts || id |
+--------------+--------------++--------------+
| 919999999999 | 0 || 2323232 |
| 918888888888 | 0 || 2323231 |
| 917777777777 | 15 || 2323233 |
+--------------+--------------++--------------+
and another table is: users_details
+--------------++--------------+
| msisdn || id |
+--------------++--------------+
| 919999999999 || 2323232 |
| 918888888888 || 2323231 |
| 917777777777 || 2323233 |
+--------------++--------------+
I want to update table 'business_details' and set total_counts = total_counts + (the counts from users_details where business_details.msisdn = users_details.msisdn and business_details.id
= users_details.id)
Can anyone help to increment to the counts of one table by matching two conditions from another table?
The basic answer to your question is to use join in an update statement.
I am going to guess that total counts in the user table refers to the number of rows. This requires aggregation before the join:
update business_details bd join
(select ud.msisdn, count(*) as cnt
from user_details ud
group by ud.msisdn
) ud
on bd.msisdn = ud.msisdn
set bd.total_counts = bd.total_counts + ud.cnt;

mysql - want to use LIMIT in IN subquery, how to workaround?

I have a query that is like this:
SELECT order_number,dr_amount FROM data WHERE order_number IN (select order_number from data where dr_machine='KBA R-' && dr_code='Tryckning' && dr_amount IS NOT NULL && dr_amount!=0 group by order_number having count(*)<2) && dr_machine='KBA R-' && dr_code='Tryckning' && dr_date>='1381442400' && id>'397433' && order_number!='16952' ORDER BY id limit 1;
The result is like this:
+--------------+-----------+
| order_number | dr_amount |
+--------------+-----------+
| 17047 | 1307 |
+--------------+-----------+
That is the result I would like to handle further.
Now i would like to add a subquery to this. I need to check that order_number (17047) in DATA WHERE oi_amount>0.
So I try to make the query to this:
SELECT order_number,dr_amount FROM data WHERE order_number IN (select order_number from data where dr_machine='KBA R-' && dr_code='Tryckning' && dr_amount IS NOT NULL && dr_amount!=0 group by order_number having count(*)<2) && dr_machine='KBA R-' && dr_code='Tryckning' && dr_date>='1381442400' && id>'397433' && order_number!='16952' && order_number in (select order_number from data where oi_amount>0) ORDER BY id limit 1;
But that gives me:
+--------------+-----------+
| order_number | dr_amount |
+--------------+-----------+
| 17046 | 653 |
+--------------+-----------+
And that is not what I want. I want to return no results from that query, because order_number 17047 has oi_amount<=0 (or NULL)
I understand that when order_number 17047 doesn't match, then it skips to next row that matches, and that is the row with order_number 17046.
So I would like to add a subquery with LIMIT 1. Like this:
SELECT order_number,dr_amount FROM data WHERE order_number IN (select order_number from data where dr_machine='KBA R-' && dr_code='Tryckning' && dr_amount IS NOT NULL && dr_amount!=0 group by order_number having count(*)<2) && order_number in (select order_number from data where dr_machine='KBA R-' && dr_code='Tryckning' && dr_date>='1381442400' && id>'397433' && order_number!='16952' ORDER BY id limit 1);
But that throws the error:
This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
My table looks like this:
+--------+--------------+-------------+------------+------------+-----------+-----------+
| id | order_number | dr_worker | dr_code | dr_machine | dr_amount | oi_amount |
+--------+--------------+-------------+------------+------------+-----------+-----------+
| 332144 | 16952 | NULL | NULL | NULL | NULL | 2000 |
| 397432 | 16952 | Gustafsson, | Intag | KBA R- | 1 | NULL |
| 397433 | 16952 | Gustafsson, | Tryckning | KBA R- | 1307 | NULL |
| 397434 | 17047 | Gustafsson, | Intag | KBA R- | 1 | NULL |
| 397435 | 17047 | Gustafsson, | Tryckning | KBA R- | 1307 | NULL |
+--------+--------------+-------------+------------+------------+-----------+-----------+
As you can see order_number 17047 has no record of oi_amount, thats why I would like to return no result/empty result.
I have little knowledge of how to use JOIN, but maybe thats the way to go? I've tried som queries but I'm not sure if that even will work (all my queries with JOIN have had some syntax error, so I gave up)
Best regards
Niclas
Try using a join instead:
SELECT order_number, dr_amount
FROM data d join
(select order_number
from data
where dr_machine = 'KBA R-' and
dr_code = 'Tryckning' and
dr_amount IS NOT NULL and
dr_amount <> 0
group by order_number
having count(*) < 2
) i
on d.order_number = i.order_number
WHERE d.dr_machine = 'KBA R-' and
d.dr_code = 'Tryckning' and
d.dr_date >= '1381442400' and
d.id > '397433' and
d.order_number <> '16952'
ORDER BY id
limit 1;
Note that I changed your operators to conform to SQL standards: <> instead of != and and instead of &&. In addition, if the constants that look like numbers really are numbers, you don't need single quotes.

MySQL group by descending order

I have a table that does not contain a unique column
id | fid | ver | dir
1 || 1 || 1 || 3
2 || 2 || 1 || 2
3 || 3 || 1 || 3
4 || 3 || 2 || 3
5 || 4 || 1 || 4
6 || 5 || 1 || 5
My question is how can I select the ID of latest fid (based from ver) in dir = 3
I tried (SELECTidFROMtableWHEREdir='3' GROUP BYfidORDER BYversion) but it gives me
id
1
3
which is not the result I want to get. Here is the result I expect to have:
id
1
4
select id
from myTable t1
where dir = 3
and not exists (
select 1
from myTable t2
where t1.version < t2.version
and t1.dir = t2.dir
and t1.fid = t2.fid
)
order by version
SELECT MAX(id) FROM table WHERE dir = '3' GROUP BY fid ORDER BY version
Try group by Version instead,
SELECT id FROM table WHERE dir='3' GROUP BY version