Joining multiple tables in one - mysql

I'm revising my previous scenario, I want to know the serial details placed in SALES ORDER versus serial details order filled in DELIVERY RECEIPTS if its correct. There are three tables below, (1)TABLE A - this is my current output upon executing the script below. (2) TABLE B - another table that I want to join (TABLE B) because of serial details. (3) TABLE DESIRED output - i want to achive.. considering :
if basetype = 17 then it should insert serial in another column (SO_SERIAL)
and if basetype =15 then it should insert serial details in another coloumn (DR_SERIAL).
By means of this, I was able to analyze that serial used in SO is different/same as used in DR.
Thanks for your help.
select a.CardCode 'BPNAME', c.itemcode, a.DocEntry 'SO_DOCENTRY', a.DocNum 'SO Num', c.ObjType'SO_Btype',
b.docEntry 'DR_DOCENTRY',b.BaseRef 'DR_num',b.ObjType 'dr_type'
from ORDR a
LEFT join dln1 b on a.docentry = b.baseentry
left join RDR1 c on a.DocEntry = c.DocEntry
Table A.
BP ITEMCODE SO_DOCENTRY SO_NUM SO_BTYPE DR_DOCENTRY DR_NUM DR_TYPE
======================================================================================
CITALI TYB20001M 144900 20152733 17 130775 20152733 15
Table B.
SERIAL ITEMCODE BASEENTRY BASENUM BASETYPE QUANTITY CARDCODE
=====================================================================================
MCWF-12001-20120601 TYB20001M 144900 20152733 17 10.000000 CITALI
MBAL-13001-20130101 TYB20001M 130775 103073 15 5.000000 CITALI
Desired Output:
BP ITEMCODE SO_NUM SO_BTYPE SO_SERIAL DR_NUM DR_TYPE DR_SERIAL
============================================================================================
CITALI TYB20001M 20152733 17 MCWF-12001-20120601 20152733 15 AL-13001-20130101

By means of this, I was able to analyze that serial used in SO is different/same as used in DR.
To match so entries with dr entries you can join table b twice, first time take 'so' entries then second time take 'dr' entries. So you will get "header", "SoEntry", "DrEntry". Then you can compare them. Take this example
select t1.BP, t1.ITEMCODE, t21.Serial as SO_SERIAL, t22.SERIAL as DR_Serial
FROM table1 t1
LEFT JOIN table2 t21 on t21.ITEMCODE=t1.ITEMCODE and t21.BASETYPE=17
LEFT JOIN table2 t22 on t22.ITEMCODE=t1.ITEMCODE and t22.BASETYPE=15

You need to learn basic joins.
Definitely you will have to join these two table.
Here is a good link from where you can start with
http://www.w3schools.com/sql/sql_join.asp
https://stackoverflow.com/questions/7877720/the-best-tutorial-on-joins-in-mysql

I see your problem. you need to join over itemcode and BASETYPE.
so try this:
select A.BP
, A.ITEMCODE
, A.SO_NUM
, A.SO_BTYPE
, B.serial as SO_SERIAL
, A.DR_NUM
, A.DR_TYPE
, A.DR_SERIAL
from a
join b on a.itemcode = b.itemcode and a.so_btype = b.basetype

Related

Getting max revision number from a view is not working as I thought?

Using MySQL 5.6. I have a view that grabs from one main table called listquotes, and a few other items from other tables. The import columns in the table that are also in the view are Quote # and Revision. We might have 5 different revisions of the same quote number, so our table would look like
id .... Quote# Revision
================================
1 1234 1
2 1234 2
3 1234 3
4 1234 4
5 1234 5
Now on my application GUI we have a dropdown that should allow you to only see the most recent revisions of every quote. Here's how I try to do that
SELECT
...columns...
FROM view_allQuoteInfo
LEFT JOIN listcustomers c ON c.id = view_allQuoteInfo.customerId
WHERE 1=1 AND view_allquoteinfo.customerId = 2453 AND view_allquoteinfo.quoteStatusId = 2 AND view_allquoteinfo.Revision = (SELECT max(t.Revision) FROM view_allquoteinfo t WHERE view_allquoteinfo.`Quote #` = t.`Quote #`)
ORDER BY idx DESC
However, this is not giving me the results I want. Here's an analysis for tihs specific customer I did in excel, some quotes that only have one revision are not showing up like 6668 while others like 4730 which has two revisions is working properly
The where clause for the All table in excel is
1=1
AND view_allquoteinfo.customerId = 2453
AND view_allquoteinfo.quoteStatusId = 2
and the clause for the Latest Table is
1=1
AND view_allquoteinfo.customerId = 2453
AND view_allquoteinfo.quoteStatusId = 2
AND view_allquoteinfo.Revision =
(SELECT max(t.Revision)
FROM view_allquoteinfo t
WHERE view_allquoteinfo.`Quote #` = t.`Quote #`)
the only difference being me trying to get the mlatest revision. The logic looks right to me but obviously MySQL is not interpreting it the way I thought it would.
Any clue as to why it's not working or how I would fix it?
I would expect to see quote 6668 revision one and quote 5963 revision 4 in my "Latest" table, while quote 5963 revision 1,2,3 would not be there.
the condition WHERE view_allquoteinfo.Quote # = t.Quote # inside the subqiery is not clear ( t and view_allquoteinfo are the same table)
so try using a join on subquery group by quote
SELECT
...columns...
FROM view_allQuoteInfo
INNER JOIN (
SELECT v.`Quote #` my_quote, max(v.Revision) max_rev
FROM view_allquoteinfo v
GRUP BY v.`Quote #`
) t ON t.my_quote = view_allQuoteInfo.`Quote #`
AND t.max_rev = view_allQuoteInfo.Revision
LEFT JOIN listcustomers c ON c.id = view_allQuoteInfo.customerId
WHERE view_allquoteinfo.customerId = 2453
AND view_allquoteinfo.quoteStatusId = 2
ORDER BY idx DESC
I figured out a way that works for me. When the user wants all quotes, I leave it the way it is.
When the user wants only the latest revisions, I modify my select query to say
SELECT ...., MAX(view_allquoteinfo.Revision) as 'Revision',...
and then I add a
GROUP BY view_allquoteinfo.'Quote #'.

How to retrieve Closest date from another table dynamically MySQL

I have two tables:
INFO table
ID LockDate Investor
157 10/15/2018 TEST1
VF1 09/02/2018 TEST2
LO2 05/01/2018 TEST3
09K 03/03/2012 TEST4
098 05/01/2012 TEST5
099 09/09/2012 TEST6
2YT 08/25/2012 TEST7
NUMBERS table
Dates Amount
10/10/2018 25.10
08/31/2018 200.15
05/10/2018 15.251
03/03/2012 10.10
05/10/2012 15.251
08/31/2012 548.0
I want the query to select all the values in the INFO table and find the closest or equal date in the Numbers table and give me the Amount. So my results would be:
ID LockDate Investor Amount
157 10/15/2018 TEST1 25.10
VF1 09/02/2018 TEST2 200.15
LO2 05/01/2018 TEST3 15.251
09K 03/03/2012 TEST4 10.10
098 05/01/2012 TEST5 15.251
099 09/09/2012 TEST6 548.0
2YT 08/25/2012 TEST7 548.0
By closest I mean equal or closest one whether it is lesser or greater than lock date.
This is the query I'm using but it is just retrieving the greater or equal one which doesn't work at all for me since I have to do it dynamically...
SELECT I.* ,
N.Amount FROM
(
SELECT A.*, MIN(NUM.Dates) AS XDATE
FROM INFO A
INNER JOIN NUMBERS AS NUM
ON NUM.Dates >= A.LockDate
GROUP BY A.ID
)AS RES
INNER JOIN NUMBERS AS N
ON N.Dates = I.XDATE
I will appreciate any help.
You just need to find the absolute minimum value for LockDate minus Dates. This will give you the closest date; lesser or greater. Rest is easy.
SELECT info.*, numbers.*
FROM info
INNER JOIN (
SELECT ID, MIN(DATEDIFF(GREATEST(LockDate, Dates), LEAST(LockDate, Dates))) Delta
FROM info
CROSS JOIN numbers
GROUP BY ID
) g ON info.ID = g.ID
INNER JOIN numbers ON DATEDIFF(GREATEST(LockDate, Dates), LEAST(LockDate, Dates)) = g.Delta
SQL Fiddle
Not sure what is your definition of "closest".
Here is my approach to get dates<=LockDate
http://sqlfiddle.com/#!9/8eea46/8
SELECT i.*, n.amount
FROM info i
LEFT JOIN numbers n
ON i.LockDate >= n.dates
LEFT JOIN numbers n_all
ON i.LockDate >= n_all.dates
AND n_all.dates > n.dates
WHERE n_all.dates IS NULL
Note: expected result is different since the definition of "closest" kind changed.
PS
Q: Why do I think that is a good approach?
A: Because whenever we deal with the data related to the timeline usually we expect data to know what (state, events, results) was before the moment we have on the timeline but not what will happen in future. That mean 31/12/2017 line/record can have/collect data from any table/records before 31/12/2017 but none from 2018. This strategy helps to keep reports consistent. They less dependent on the date when we generate the report. if we generate report about Dec 2017 at 1st Jan 2018 it will output same result as if we generate same report on same period Dec 2017 but week or month later 10th Jan 2018 or 1st of Feb.

SQL unwanted results in NOT query

This looks like it should be really easy question, but I've been looking for an answer for the past two days and can't find it. Please help!
I have two tables along the lines of
texts.text_id, texts.other_stuff...
pairs.pair_id, pairs.textA, pairs.textB
The second table defines pairs of entries from the first table.
What I need is the reverse of an ordinary LEFT JOIN query like:
SELECT texts.text_id
FROM texts
LEFT JOIN text_pairs
ON texts.text_id = text_pairs.textA
WHERE text_pairs.textB = 123
ORDER BY texts.text_id
How do I get exclusively the texts that are not paired with A given textB? I've tried
WHERE text_pairs.textB != 123 OR WHERE text_pairs.textB IS NULL
However, this returns all the pairs where textB is not 123. So, in a situation like
textA TextB
1 3
1 4
2 4
if I ask for textB != 3, the query returns 1 and 2. I need something that will just give me 1.
The comparison on the second table goes in the ON clause. Then you add a condition to see if there is no match:
SELECT t.text_id
FROM texts t LEFT JOIN
text_pairs tp
ON t.text_id = tp.textA AND tp.textB = 123
WHERE tp.textB IS NULL
ORDER BY t.text_id ;
This logic is often expressed using NOT EXISTS or NOT IN:
select t.*
from texts t
where not exists (select 1
from text_pairs tp
where t.text_id = tp.textA AND tp.textB = 123
);

Join and show latest Event

I need to generate a related of all "Tickets" that is open and with status "Analysis",i need to do a join in two tables.
The first one:
SELECT TOP 1000
[nsu_sugestao]
,[num_sugestao_papel]
,[edv_promotor]
FROM [NovoCLIC].[dbo].[Sugestao]
Exemplo of this select:
nsu_sugestao num_sugestao_papel edv_promotor
1 372759 92602045
In this one, num_sugestao_papel is the number of the ticket, edv_promotor is the person the owns it.
The second one:
SELECT TOP 1000
[iClic]
,[iStatus]
,[dtDateCreated]
FROM [NovoCLIC].[dbo].[T_STATUS_CLIC]
Exemple:
iClic iStatus dtDateCreated
1 1 1999-01-25 13:33:00.000
The iClic is the ticket number, the iStatus is the status currently and dtDateCreated.
I need to show all Tickets the the last status is analysis, the status analysis is the number 2 in iStatus column, i don't need the tickets that already are in different numbers than 2.
SELECT TOP 1000 [nsu_sugestao]
-- ,n.num_sugestao_papel
-- ,n.edv_promotor
-- ,s.iStatus
-- ,s.dtDateCreated
-- FROM [NovoCLIC].[dbo].[Sugestao]
-- with
-- select s.dtDateCreated,MAX(s.EventDate)latestDate
-- from [NovoCLIC].[dbo].[T_STATUS_CLIC] s
-- right join [NovoCLIC].[dbo].[T_STATUS_CLIC] s on [NovoCLIC].[dbo].[Sugestao] =
I'm trying something like this, but I'm getting a lot of errors.
Try the code given below and provide us feedback
SELECT
S.[nsu_sugestao]
,S.[num_sugestao_papel]
,S.[edv_promotor]
,T.[iClic]
,T.[iStatus]
,T.[dtDateCreated]
FROM [NovoCLIC].[dbo].[Sugestao] S
INNER JOIN [NovoCLIC].[dbo].[T_STATUS_CLIC] T on S.nsu_sugestao = T.iClic
INNER JOIN (
SELECT
[iClic]
,Max([dtDateCreated]) As LatestDateCreated
FROM
[NovoCLIC].[dbo].[T_STATUS_CLIC]
GROUP BY
[iClic]
) TM ON T.iClic = TM.iClic AND T.dtDateCreated = TM.LatestDateCreated
WHERE
T.iStatus = 2

How to dynamically create a pivot table on MySQL

I'm having difficulties creating the result i want on a specific situation.
I have a two tables:
1: sales by warehouse:
+-------------+---------------+--------------+
warehouse | type -------- | value
+-------------+---------------+--------------+
A--------------XX-------------234234----------
A-------------- YY------------ 234343--------------
A-------------- ZZ------------ 534534--------------
B-------------- XX------------ 234432--------------
B-------------- YY------------ 767563--------------
B-------------- ZZ------------ 312332--------------
c-------------- XX------------ 234234--------------
....
2: users by warehouse:
user--------|---warehouse
john--------|-- A
john--------|-- B
john--------|-- C
peter-------|-- A
Daniel------|-- C
Kim---------|-- B
Kim---------|-- C
....
So i created this query:
select a.warehouse, type, value from sales_by_warehouse A
left join users_warehouse B
ON A.warehouse=B.warehouse
where b.user = 'user_logged_on_software'
This works perfectly by giving me the warehouse that the user has access to and its values but, now, i wanted to invert the result such as in a pivot table so that if the user was Peter, this would be the result:
type--|-----A----
XX----|-----123123
YY----|-----3423423
ZZ----|-----3423345
And if the user was kim:
type--|-----B---------|-----C
XX----|-----123123-|---234324
YY----|-----423423-|---245435
ZZ----|-----423345-|---456233
Is there a way to do this with only select statements, without views or PS?