I am trying to get the structure of parent/ child via sql query.
I have this code:
state_code, description
A000
A010
B000
B010
B01A
B01B
B020
B02A
I want a structure like parent_id, element_id and desc
Such that:
A
A000
-01 (from A)
--A010
B
B000
-01
--B010
--B01A
-02
--
I tried it using this code, but unfortunately it doesn't work.
select distinct
SUBSTRING(REPLACE(state_cd,'0',''),1, LEN(REPLACE(state_cd, '0', '')) -1) AS parent_id, REPLACE(state_cd,'0','') state_id,
state_cd,
desc_1
from
CATEGORYSTRUCTURE
inner join
CATEGORYITEMS on CATEGORYSTRUCTURE.struct_id = CATEGORYITEMS.struct_id
left join
STATECODES on key_1 = state_cd
where
state_type = '22'
UNION ALL
select distinct
SUBSTRING(REPLACE(state_cd,'0',''),1, LEN(REPLACE(state_cd, '0', '')) -1) AS parent_id,
REPLACE(state_cd,'0','') state_id,
stat_cd,
desc_1
from
CATEGORYITEMS
inner join
STATECODES on key_1 = state_cd
where
state_type = '22'
My result:
parent_id stat_id stat_cd desc_1
O O000 11
P P000 Pa)
Q Q000 prod
R R000 Zus
S S000 Ver
T T000 Pack
A A1 A010 Get
A A1 A100 Kakt
A A3 A030 Kol
A A7 A070 Milk
A A8 A080 Spt
A1 A11 A110 Lo
A1 A1A A01A Hcht
What I want is everything under respective characters
A A7 A070 Milk
A A8 A080 Spt
A A11 A110 Lo
A1 A1A A01A Hcht
I can't understand what exactly you want, But I think this query can help you:
SELECT state_cd
, SUBSTRING(state_cd,1,1) As Parent0
, CASE WHEN state_cd Like '__[^0]_' THEN SUBSTRING(state_cd,2,2) ELSE '' END As Parent1
, CASE WHEN state_cd Like '___[^0]' THEN SUBSTRING(state_cd,4,1) ELSE '' END As Parent2
FROM yourTable
Related
I have two tables which are related in the following way:
Table A is a list of college courses and instances of that course, for example the "course" Maths runs on a Tuesday and a Thursday and therefore has two "course_periods". This is described in the following table:
Table A
id
name
type
0001
Maths
course
0002
Maths (Thursday)
course_period
0003
Maths (Tuesday)
course_period
There is another table which connects all the "course periods" to their parent "courses" and looks like this:
Table B
id
source
destination
0001
0001
0002
0002
0001
0003
I would like to produce the last below table which joins the two tables A & B in the following way:
destination_id
name_course_period
source_id
name_course
0002
Maths(Thursday)
0001
Maths
0003
Maths(Tuesday)
0001
Maths
I simply can't find the correct join statement to produce the desired result.
You must join TableB to 2 copies of TableA:
SELECT b.destination destination_id,
a2.name name_course_period,
b.source source_id,
a1.name name_course
FROM TableB b
INNER JOIN TableA a1 ON a1.id = b.source
INNER JOIN TableA a2 ON a2.id = b.destination;
See the demo.
Recreating your tables as cte, you need to start with table a as your base table. Join this table to b.
You then need to join back to a to get the name of the destination.
with a as (
select '0001' id, 'Maths' name, 'course' type
union all select '0002', 'Maths (Thursday)','course_period'
union all select '0003', 'Maths (Tuesday)', 'course_period'
)
, b as (
select '0001' id, '0001' source, '0002' destination
union all select '0002', '0001', '0003'
)
select
b.id as destination_id
, ref.name as name_course_period
, b.source as source_id
, a.name as name_course
from a
inner join b on b.source = a.id
inner join a ref on ref.id = b.destination --join back to a for name
Need a help with sql query.
I have 2 tables.
Matches.
first_referee_arbitr_id
second_referee_arbitr_id
home_team
guest_team
date
Arbitrs.
id
name
surname
first_referee_arbitr_id and second_referee_arbitr_id are from Arbitrs table(id).
As the result I need to count how much each referee has been included in matches:
referee_first_count | referee_second_count | Arbitr Surname | Arbitr Name
My query now:
SELECT T1.referee_first_count, T2.referee_second_count, T1.surname, T1.name
FROM (
select matches.first_referee_arbitr_id, q.surname, q.name, count(*) AS referee_first_count
FROM matches
JOIN (
SELECT name, surname, id
FROM arbitrs
) as q ON matches.first_referee_arbitr_id=q.id
GROUP BY matches.first_referee_arbitr_id, q.name, q.surname
ORDER BY referee_first_count DESC
) T1 FULL OUTER JOIN
(
select matches.second_referee_arbitr_id, arbitr.surname, arbitr.name, count(*) AS referee_second_count
FROM matches
JOIN (
SELECT name, surname, id
FROM arbitrs
) as arbitr ON matches.second_referee_arbitr_id=arbitr.id
GROUP BY matches.second_referee_arbitr_id, arbitr.name, arbitr.surname
ORDER BY referee_second_count DESC
) T2
ON (
(T1.name = T2.name) AND (T1.surname = T2.surname)
)
Example
Arbitrs:
id | Name | Surname
1 John Rambler
2 Steve Crystler
3 Tom Ferguson
Matches:
first_referee_arbitr_id| second_referee_arbitr_id| home_team | guest_team | date
1 Chelsea Everton 22.06.2020
2 1 Liverpool Lester 28.06.2020
3 Dinamo K Dinamo M 06.07.2020
1 2 Juventus Dinamo K 10.10.2020
3 Dinamo K Chelsea 20.20.2020
Result:
referee_first_count | referee_second_count | surname | name
2 1 Rambler John
1 1 Crystler Steve
2 0 Ferguson Tom
My result now with query above:
referee_first_count | referee_second_count | surname | name
2 1 Rambler John
1 1 Crystler Steve
2 NULL NULL NULL
First aggregate the matches table (twice) and left join this to the Arbitrs table:
SELECT a.name , a.Surname , ISNULL(fir.first_count,0) , ISNULL( sec.sec_count,0)
FROM Arbitrs a
LEFT JOIN (
SELECT first_referee_arbitr_id,COUNT(*) as first_count
FROM Matches
GROUP BY first_referee_arbitr_id
) fir
ON fir.first_referee_arbitr_id = a.id
LEFT JOIN (
SELECT second_referee_arbitr_id,COUNT(*) as sec_count
FROM Matches
GROUP BY second_referee_arbitr_id
) sec
ON sec.second_referee_arbitr_id = a.id
SELECT
a.name
, a.surname
, COUNT(CASE WHEN m1.id IS NOT NULL THEN 1 end) referee_first_count
, COUNT(CASE WHEN m2.id IS NOT NULL THEN 1 end) referee_second_count
FROM
Arbitrs a
LEFT JOIN macthes m1
ON a.id = m.first_referee_arbitr_id
LEFT JOIN macthes m2
ON a2.id = m.second_referee_arbitr_id
GROUP BY
a.name
, a.surname
-- if you want to show only those with refrence
HAVING referee_first_count > 0 or referee_second_count > 0
I have 2 queries both use joins, select various columns from multiple tables which produce the below result sets:
companyID workType contractnumber employeenumber Value2
1 1C 9999999 111111 2547.21
1 1C 9999999 222222 863.67
1 1C 9999999 333333 2962.15
1 1C 9999999 444444 1971.61
1 1C 9999999 555555 152.41
1 1C 9999999 666666 155.90
1 1C 9999999 777777 657.20
companyID normalWorkType employeeNumber value1
1 1C 11111 1016.08
1 1C 22222 3118.05
1 1C 33333 2628.81
1 61 44444 2547.21
I'm looking to join these to produce the below result.. can anyone explain what the correct syntax would be?
companyID normalWorkType contractnumber employeeNumber value1 Value2
1 1C 9999999 11111 1016.08 2547.21
1 1C 9999999 22222 3118.05 863.67
1 1C 9999999 33333 2628.81 2962.15
1 61 9999999 44444 2547.21 1971.61
1 1C 9999999 55555 0 152.41
1 1C 9999999 66666 0 155.90
1 1C 9999999 77777 0 657.20
Grouping above is on companyID & employeeNumber
Try LEFT OUTER JOIN:
SELECT t1.companyID,
t2.normalWorkType,
t1.contractnumber,
t1.employeeNumber,
coalesce(t2.value1,0) as t2.value1,
t1.value2
FROM DatabaseName.t1 AS t1 LEFT OUTER JOIN
DatabaseName.t2 AS t2 ON t1.employeenumber = t2.employeenumber
AND t1.companyID = t2.companyID
I'm assuming here that the contract numbers in the proposed result set are actually the contract numbers from your first query, and that the difference is just a typo. If that's true, this will get you what you want.
SELECT
q1.companyID
COALESCE(q2.normalWorkType,q1.workType) AS normalWorkType
q1.contractnumber
q1.employeeNumber
COALESCE(q2.value1 ,0) as value1
q1.Value2
FROM
(
<Your first query>
) as q1
LEFT JOIN
(
<Your second query>
) as q2
ON
q1.companyID = q2.companyID
AND
q1.employeeNumber = q2.employeeNumber;
Try below Query
select Table1.companyId,Table2.normalworktype,Table1.contractnumber,
Table1.employeenumber,Table2.value1,Table1.value2
from Table1
inner join Table2 on Table1.companyid = Table2.companyid
and Table1.employeeNumber=Table2.employeeNumber
Thanks for the responses everyone,
After trying Husam Ebish's suggestion It wasn't quite what I needed but lead me to this thread. (up-voted your answer)
How to combine two query results into one and I have different column name
What I really found useful was this bit of information highlighted below from the linked thread. After trying the different "left" joins suggested the comment's highlighted lead me to try "full outer join" which has given me the correct result-set.
If you only have one row from each query, it's just a CROSS JOIN
SELECT
*
FROM
(query1) AS q1
CROSS JOIN
(query2) AS q2
If you have more than one row from each query, you need an INNER JOIN
or maybe a FULL OUTER JOIN and some relationship between the two sets
of data
SELECT
*
FROM
(query1) AS q1
FULL OUTER JOIN
(query2) AS q2
ON q2.id2 = q1.id1
Note:
UNION appends data vertically
JOIN appends data horizontally
SELECT
*
FROM
(select top 1 VL1,VL2,VL3 from current_voltage AS q1
where deviceimei ='233'
order by devicetimestamp) AS q1
CROSS JOIN
(select top 1 OTI,WTI,ATI from overview AS q2
where deviceimei ='233'
order by devicetimestamp ) AS q2
You can put your search result to 2 temp table and then join this 2 temp table or use alliance for your each select and then join them.
like :
SELECT
*
FROM (
SELECT
companyID
,workType
,contractnumber
,employeenumber
,Value2
FROM table1
) t1
INNER JOIN (
SELECT
companyID
,normalWorkType
,contractnumber
,employeeNumber
,value1
,Value2
FROM table2
) t2
ON t1.companyID = t2.companyid
or put your result 2 different temp table and then join them
SELECT
companyID
,workType
,contractnumber
,employeenumber
,Value2
INTO #tt1
FROM table1
SELECT
companyID
,normalWorkType
,contractnumber
,employeeNumber
,value1
,Value2
INTO #tt2
FROM table2
SELECT *
FROM #tt1 t1
INNER JOIN #tt2 t2 ON t1.companyid = t2.companyID
I have three tables (simplified version - the whole picture is a bit more complex).
TABLE: CUSTOMER TABLE: PURCHASE1 TABLE: PURCHASE2
=============== ======================= =======================
CustomerID CustomerID | ProductID CustomerID | ProductID
--------------- ------------|---------- ------------|----------
1 1 | 51 1 | 81
2 1 | 52 1 | 82
3 2 | 52 1 | 83
I know the table structure isn't the best but that's not what I need help with. The products held in the purchase tables are of different types, if that helps to provide context.
I'm trying to join the tables, using a query like this:
Select
customer.customerid, purchase1.productid as P1,
purchase2.productid as P2
From
customer
Left join
purchase1 on customer.customerid = purchase1.customerid
Left join
purchase2 on customer.customerid = purchase2.customerid
Where
customer.customerid = 1;
This produces the following:
CustomerID | P1 | P2
--------------------
1 | 51 | 81
1 | 51 | 82
1 | 51 | 83
1 | 52 | 81
1 | 52 | 82
1 | 52 | 83
How do I get it to do this instead?
CustomerID | P1 | P2
-----------|------|---
1 | 51 | null
1 | 52 | null
1 | null | 81
1 | null | 82
1 | null | 83
The first table has a row for every combination of P1 and P2. The second table only has a row for each customer-product combination.
Can I do this without using UNION? The reason I ask, is that because the query will become more complex, using columns from other rows that aren't in PURCHASE1 or PURCHASE2.
If I have to use UNION, how can I do it such that I can still select from other tables and have additional columns in my query?
Use Union . See DEMO. In union, you have to have same number of columns in both queries so use NULL to match number of column in both query
Select * from (Select customer.customerid, purchase1.productid as P1, NULL as P2
from customer
INNER join purchase1
on customer.customerid = purchase1.customerid
UNION ALL
Select customer.customerid, NULL as P1, purchase2.productid as P2
from customer
INNER join purchase2
on customer.customerid = purchase2.customerid) tb
where tb.customerid = 1;
I would do it this way:
select customerid, p1, p2
from customer
left join (
select customerid, productid p1, null p2 from purchase1
union all
select customerid, null p1, productid p2 from purchase2
) using (customerid)
where customerid = 1;
SQLFiddle demo
Now you can attach rest of tables without repeated logic.
I would first of all union up all the tables and then join them to the customer table - like so:
with customer as (select 1 customerid, 'bob' name from dual union all
select 2 customerid, 'ted' name from dual union all
select 3 customerid, 'joe' name from dual),
purchase1 as (select 1 customerid, 51 productid from dual union all
select 1 customerid, 52 productid from dual union all
select 2 customerid, 52 productid from dual),
purchase2 as (select 1 customerid, 81 productid from dual union all
select 1 customerid, 82 productid from dual union all
select 1 customerid, 83 productid from dual),
-- end of mimicking your table and data; main query is below:
purchases as (select customerid, productid productid1, null productid2
from purchase1
union all
select customerid, null productid1, productid productid2
from purchase2)
select c.customerid,
c.name,
p.productid1,
p.productid2
from customer c
inner join purchases p on (c.customerid = p.customerid)
order by c.customerid,
p.productid1,
p.productid2;
CUSTOMERID NAME PRODUCTID1 PRODUCTID2
---------- ---- ---------- ----------
1 bob 51
1 bob 52
1 bob 81
1 bob 82
1 bob 83
2 ted 52
It's probably easiest to just change it to a union query like this.
select customer.customerid, purchase1.productid as P1, null as P2
from customer
left join purchase1
on customer.customerid = purchase1.customerid
union all
select customer.customerid, null as P1, purchase2.productid as P2
from customer
left join purchase2
on customer.customerid = purchase2.customerid
where customer.customerid = 1;
This uses Union, but in a slightly different way, within subqueries, which might provide you more flexibility.
select distinct t1.pID,t2.pID
from (select ID,pID from Puchase1
union all
select ID, null from Purchase1) t1
right join (select ID,pID from Purchase2
union all
select ID, null from Purchase2) t2
on t1.ID = t2.ID
where t1.ID = 1
and (t1.pID is not null or t2.pID is not null)
and (t1.pID is null or t2.pID is null)
I have got a requirement to display a query which shows matching and non matching rows against the master lookup table
The #PostCodes table contains the postcodes for master table which the second query would be matched against
DECLARE #PostCodes TABLE
(
RowID int not null primary key identity(1,1),
Postcodes varchar(100)
)
SELECT
C.CampaignId, C.Name, C.Description,C.EndedOn, C.Active, C.Manager,
P.PostcodeArea, P.PostcodeDistrict
FROM
Campaign C, CampaignPostcode P, #PostCodes pc
WHERE
P.CampaignId = C.CampaignId AND
P.PostcodeDistrict = pc.Postcodes AND
C.EndedOn IS NULL
The second query returns me only the matching records against postcodes and I have tried everything to include unmatched records but no luck.
Any help?
EDIT (Tables)
PostCodes (table1) Campaign (table2)
Id Postcodes CampaignId Name Desc
1 AA 1 camp1 Desc1
2 AB 2 camp2 Desc2
3 AC 3 camp3 Desc3
4 AD 4 camp4 Desc4
CampaignPostcode (table3)
CampaignPostcodeId CampaignId PostcodeArea
1 1 AA
2 2 AB
3 2 AB
4 3 AC
Output Required
Id CampaignName Desc PostcodeIn PostcodeOut
1 Camp1 Desc1 AA NULL
2 Camp2 Desc2 AB NULL
3 Camp2 Desc2 AB NULL
4 Camp3 Desc3 AC NULL
5 Camp4 Desc4 NULL AD
What about this:
SELECT
C.CampaignId, C.Name, C.Description,C.EndedOn, C.Active, C.Manager,
P.PostcodeArea, P.PostcodeDistrict
FROM
Campaign C
INNER JOIN
CampaignPostcode P ON P.CampaignId = C.CampaignId
LEFT OUTER JOIN
#PostCodes pc ON P.PostcodeDistrict = pc.Postcodes
WHERE
C.EndedOn IS NULL
Try this instead:
SELECT
p.*
FROM #PostCodes AS PC
LEFT JOIN
(
SELECT *
FROM Campaign C
INNER JOIN CampaignPostcode P ON P.CampaignId = C.CampaignId
) AS p ON P.PostcodeDistrict = pc.Postcodes
WHERE P.EndedOn IS NULL