SQL select from 3 table - sql

I have 3 tables:
ssu:
id (primary key)
ssu_number
agreement:
agreement_id
agreement_number
agreement_status_fk
agreement_type_fk
agreement_ssu:
ssu_id
agreement_fk
I need to select ssu_number which occur at least 2 times as ssu_id in table agreement_ssu, which have agreement_status_fk = 1 and agreement_type_fk = 1.
Here is my select but i think it will be not work (i cant test it now):
select
*
from
asd.ssu p
join tdd.agreement_ssu ap on p.id = ap.ssu
join tdd.agreement ae on ae.id = ap.AGREEMENT_FK
join
(
select
ssu_id
from
tdd.agreement_ssu
group by
ssu_ID
having
count( ssu_id ) > 1 )
y on y.ssu_id = p.ID
where
ae.AGREEMENT_TYPE_FK = 1
and
ae.agreement_status_fk = 1;
Example
ssu
| id | ssu_number|
| 1 | 2000 |
| 2 | 2001 |
| 3 | 2002 |
| 4 | 2003 |
agreement
| agreement_id | agreement_number | agreement_status_fk | agreement_type_fk |
| 1 | da5as6d | 1 | 1 |
| 2 | d57as6 | 1 | 2 |
| 3 | dsjks6d | 2 | 2 |
| 4 | d4s7sad | 1 | 1 |
| 5 | d43790d | 1 | 1 |
| 6 | d437s6d | 1 | 1 |
| 7 | d4aq36d | 1 | 2 |
agreement_ssu
| ssu_id | agreement_fk |
| 1 | 1 |
| 1 | 2 |
| 2 | 6 |
| 2 | 4 |
| 2 | 7 |
| 3 | 3 |
| 4 | 5 |
And from select i should get only ssu_number: 2001 (occurs 2 times in agreement_ssu and both have agreement_status_fk = 1 and agreement_type_fk = 1)
| ssu_number |
| 2001 |

I have not setup the exact scenario, and not checked this code, but I think something along these lines is what you want:
SELECT
ssu.ssu_number
FROM
ssu
INNER JOIN
(
SELECT
assu.ssu_id
FROM
agreement_ssu assu
INNER JOIN
agreement a on a.agreement_id = assu.agreement_fk
GROUP BY
assu.ssu_id
WHERE
a.agreement_status_fk = 1
AND a.agreement_type_fk = 1
HAVING
COUNT(assu.ssu_id) > 1
) IT ON ssu.id = IT.ssu_id
Regards...

This should do it,
SELECT SSU.SSU_NUMBER
FROM SSU
JOIN AGREEMENT_SSU
ON SSU.ID = AGREEMENT_SSU.SSU_ID
JOIN AGREEMENT
ON AGREEMENT.ID = AGREEMENT_SSU.AGREEMENT_FK
WHERE AGREEMENT.AGREEMENT_STATUS_FK = 1
AND AGREEMENT.AGREEMENT_TYPE_FK = 1
GROUP BY SSU.SSU_NUMBER
HAVING COUNT(*) > 1;

Related

Use information cells instead of column heads

I had trouble reporting information and building View
My table information is as follows
DataBase
Table Stu
---------------------------------------------------
----------------------< Stu >----------------------
---------------------------------------------------
| id | name | age|id_Orientation | id_StudyStatus|
---------------------------------------------------
| 1 | John | 24 | 1 | 1 |
| 2 | Sara | 23 | 1 | 2 |
| 3 | Mary | 26 | 1 | 3 |
| 4 | Jax | 25 | 2 | 1 |
| 5 | izable| 22 | 2 | 2 |
| 6 | Tari | 23 | 2 | 3 |
| 7 | Kap | 26 | 3 | 1 |
| 8 | Lio | 25 | 3 | 2 |
| 9 | Soti | 22 | 3 | 3 |
---------------------------------------------------
Table StudyStatus
-----------------
--<StudyStatus>--
-----------------
| id | name |
-----------------
| 1 | Studying |
| 2 | Cancel |
| 3 |laying off|
-----------------
Table Orientation
-------------------
---<Orientation>---
-------------------
| id | name |
-------------------
| 1 | IT |
| 2 |Construction|
| 3 | Medical |
-------------------
[The output I finally want]
----------------------------------------------------------
----------------------< Stu >------------------------------
-----------------------------------------------------------
| id | name | All | Studying | Cancel | layingOff |
---------------------------------------------------
| 1 | IT | 3 | 1 | 1 | 1 |
| 2 |Construction| 3 | 1 | 1 | 1 |
| 3 | Medical | 3 | 1 | 1 | 1 |
-----------------------------------------------------------
By What Query ?
Please Help ... !
Thanks
Try it. but first remove the Blank Space of Left & Right Side from the Name of StudyStatus.
select isnull([Studying],0)+isnull([Cancel],0)+isnull([Laying off],0) [All], Orientation_Name,[Studying],[Cancel],[Laying off]
from
(
select s.id,o.Name Orientation_Name ,ss.Name StudyStatus_Name
from Stu s inner join StudyStatus ss on s.ID_StudyStatus=ss.ID inner join Orientation O on o.Id=s.ID_Orientation)as st
pivot
(
count(id)
FOR StudyStatus_Name IN ([Studying],[Cancel],[laying off])
) as PV
You can go for conditional sum and get the results.
SELECT o.name,
COUNT(*) AS All,
SUM(CASE WHEN ss.Name = 'Studying' THEN 1 ELSE 0 END) AS Studying,
SUM(CASE WHEN ss.Name = 'Cancel' THEN 1 ELSE 0 END) AS cancel,
SUM(CASE WHEN ss.Name = 'Laying Off' THEN 1 ELSE 0 END) AS LayingOff
FROM Orientation as o
inner join Stu as s
on s.id_orientation = s.id
inner join StudyStatus AS ss
on ss.id = s.id_StudyStatus
GROUP BY o.name
select isnull([Studying], 0) + isnull([Cancel], 0) + isnull([laying off], 0) [All],
Orientation_Name,
[Studying],
[Cancel],
[laying off]
from (
select s.id,
o.name Orientation_Name,
ss.name StudyStatus_Name
from Stu s
inner join StudyStatus ss on ss.id = s.id_StudyStatus
inner join Orientation o on o.id = s.id_Orientation
) as st pivot (
count(id) FOR StudyStatus_Name IN ([Studying], [Cancel], [laying off])
) as PV
Pay attention to uppercase and lowercase letters Move Inner Join
Thanks to #LiaqatKundi and #DaleK

Sum with 3 tables to join

I have 3 tables. The link between the first and the second table is REQ_ID and the link between the second and the third table is ENC_ID. There is no direct link between the first and the third table.
INS_RCPT
+----+--------+------+----------+
| ID | REQ_ID | CURR | RCPT_AMT |
+----+--------+------+----------+
| 1 | 1 | USD | 100 |
| 2 | 2 | USD | 200 |
| 3 | 3 | USD | 300 |
+----+--------+------+----------+
ENC_LOG
+----+--------+--------+-------------+
| ID | REQ_ID | ENC_ID | ENC_LOG_AMT |
+----+--------+--------+-------------+
| 1 | 1 | 1 | 20 |
| 2 | 1 | 2 | 50 |
| 3 | 1 | 3 | 30 |
| 4 | 2 | 4 | 20 |
+----+--------+--------+-------------+
ENC_RCPT
+----+--------+--------------+
| ID | ENC_ID | ENC_RCPT_AMT |
+----+--------+--------------+
| 1 | 1 | 10 |
| 2 | 1 | 10 |
| 3 | 2 | 15 |
| 4 | 2 | 25 |
| 5 | 2 | 10 |
| 6 | 3 | 12 |
| 7 | 3 | 18 |
| 8 | 4 | 10 |
+----+--------+--------------+
I would like to have output as follows:
+----+--------+------+----------+-------------+--------------+
| ID | REQ_ID | CURR | RCPT_AMT | ENC_LOG_AMT | ENC_RCPT_AMT |
+----+--------+------+----------+-------------+--------------+
| 1 | 1 | USD | 100 | 100 | 100 |
| 2 | 2 | USD | 200 | 20 | 10 |
| 3 | 3 | USD | 300 | 0 | 0 |
+----+--------+------+----------+-------------+--------------+
I am using SQL Server to write this query. Any help is appreciated.
One approach would be to join the first table to two subqueries which compute the sums separately:
SELECT
ir.ID,
ir.REQ_ID,
ir.CURR,
ir.RCPT_AMT,
el.ENC_LOG_AMT,
er.ENC_RCPT_AMT
FROM INS_RCPT ir
LEFT JOIN
(
SELECT REQ_ID, SUM(ENC_LOG_AMT) AS ENC_LOG_AMT
FROM ENC_LOG
GROUP BY REQ_ID
) el
ON ir.REQ_ID = el.REQ_ID
LEFT JOIN
(
SELECT t1.REQ_ID, SUM(t2.ENC_RCPT_AMT) AS ENC_RCPT_AMT
FROM ENC_LOG t1
INNER JOIN ENC_RCPT t2 ON t1.ENC_ID = t2.ENC_ID
GROUP BY t1.REQ_ID
) er
ON ir.REQ_ID = er.REQ_ID
Demo
Note that your question includes a curve ball. The second subquery needs to return aggregates of the receipt table by REQ_ID, even though this field does not appear in that table. As a result, we actually need to join ENC_LOG to ENC_RCPT in that subquery, and then aggregate by REQ_ID.
You can try the below query. Also change the join from left to inner as per your requirement.
select a.id,a.req_id,a.curr,sum(a.rcpt_amt) rcpt_amt,sum(a.enc_log_amt) enc_log_amt,sum(c.enc_rcpt_amt) enc_rcpt_amt
from
(
select a.id id ,a.req_id req_id ,a.curr curr,sum(rcpt_amt) as rcpt_amt,sum(enc_log_amt) as enc_log_amt
from ins_rcpt a
left join enc_log b
on a.req_id=b.req_id
group by id,req_id,curr
) a
left join enc_rcpt c
on a.enc_id = c.enc_id
group by id,req_id,curr;

Combine the data of two tables using SQL Pivot and joins for a subquery

I'm trying to create a report to find the number of users subscribed to the notification type.
I am stuck with subqueries because if these two tables
Table 1
NotificationMaster
+----+-------+
| ID | Name |
+----+-------+
| 1 | Email |
| 2 | Push |
| 3 | Call |
+----+-------+
Table 2
NotificationPreference
+------------+------------------+------------+--------------+
| ResourceID | NotificationID | IsChecked | AccountID |
+------------+------------------+------------+--------------+
| 23 | 1 | 1 1 |
| 36 | 2 | 0 2 |
| 45 | 3 | 1 3 |
| 23 | 1 | 0 1 |
| 36 | 2 | 1 2 |
| 45 | 3 | 0 3 |
| 23 | 1 | 1 1 |
| 36 | 2 | 0 3 |
| 45 | 3 | 1 3 |
+------------+------------------+--------------------------+
Expected Output
Notification Vs Resource Count
+----------+-------+------+------+
| Accountid Email | Push | Call |
+----------+-------+------+------+
| 1 | 2 | 1 | 2 |
+----------+-------+------+------+
Other Tables
AccountName
+----+-------+
| ID | Name |
+----+-------+
| 1 | Blues |
+----+-------+
| 2 | Jazz |
+----+-------+
| 3 | Rock |
+----+-------+
ResourceNames
+----------+----------------+-----------+
| Resource | Name | AccountID |
+----------+----------------+-----------+
| 23 | MJ | 1 |
| 36 | Paul | 1 |
| 45 | Jay Z | 3 |
+----------+----------------+-----------+
Progress Till Now
SELECT A.ID
,A.Name
,count(R.id) AS 'Total Resource Count'
,(SELECT count(DISTINCT np.resourceid)
FROM NotificationPreference np
INNER JOIN NotificationMaster nm ON np.notificationid = nm.id
WHERE np.accountid = A.ID
AND nm.id = 1
) AS 'Email'
FROM AccountName A
LEFT JOIN [ResourceNames] R ON A.ID = R.[AccountID]
LEFT JOIN NotificationPreference np ON np.resourceid = R.ID
GROUP BY A.ID
,A.Name
The basic pivot use conditional COUNT() :
SELECT Accountid
, COUNT( CASE WHEN nm.Name = 'Email' THEN 1 END ) as Email
, COUNT( CASE WHEN nm.Name = 'Push' THEN 1 END ) as Push
, COUNT( CASE WHEN nm.Name = 'Call' THEN 1 END ) as Call
FROM NotificationPreference np
JOIN NotificationMaster nm
ON np.NotificationID = nm.id
GROUP BY Accountid

Crosstab multi columns

Hello I have a problem with SQL in SQL Server 2005.
Suppose that I have a table called myTable with data as below:
| NAME | CREDIT | GRADE | YEAR | SEMESTER |
---------------------------------------------
| Name1 | 1 | A | 1 | 1 |
| Name2 | 4 | B | 1 | 1 |
| Name3 | 2 | E | 1 | 1 |
| Name4 | 7 | F | 1 | 1 |
| Name5 | 4 | A | 1 | 2 |
| Name6 | 3 | C | 1 | 2 |
| Name7 | 6 | D | 1 | 2 |
| Name8 | 1 | A | 1 | 2 |
| Name9 | 1 | A | 1 | 2 |
| Name10 | 1 | A | 1 | 2 |
| Name11 | 3 | C | 2 | 1 |
| Name12 | 6 | E | 2 | 1 |
| Name13 | 4 | C | 2 | 1 |
| Name14 | 2 | B | 2 | 2 |
| Name15 | 1 | A | 2 | 2 |
| Name16 | 1 | A | 2 | 2 |
| Name17 | 1 | A | 2 | 2 |
| Name18 | 5 | D | 3 | 1 |
| Name19 | 1 | A | 3 | 1 |
| Name20 | 1 | A | 3 | 1 |
| Name18 | 5 | D | 3 | 2 |
| Name19 | 1 | A | 3 | 2 |
| Name20 | 1 | A | 3 | 2 |
I want to output the result as below:
| NAM1 | CRDT1 | GRD1 | YEAR1 | SEMER1 | NAM2 | CRDT2 | GRD2 | YEAR2 | SEMES2 |
-----------------------------------------------------------------------------
| Name1| 1 | A | 1 | 1 |Name5 | 4 | A | 1 | 2 |
| Name2| 4 | B | 1 | 1 |Name6 | 3 | C | 1 | 2 |
| Name3| 2 | E | 1 | 1 |Name7 | 6 | D | 1 | 2 |
| Name4| 7 | F | 1 | 1 |Name8 | 1 | A | 1 | 2 |
|Name9 | 1 | A | 1 | 2 |
|Name10| 1 | A | 1 | 2 |
| Name11| 3 | C | 2 | 1 |Name14| 2 | B | 2 | 2 |
| Name12| 6 | E | 2 | 1 |Name15| 1 | A | 2 | 2 |
| Name13| 4 | C | 2 | 1 |Name16| 1 | A | 2 | 2 |
|Name17| 1 | A | 2 | 2 |
| Name18| 5 | D | 3 | 1 |Name18| 5 | D | 3 | 2 |
| Name19| 1 | A | 3 | 1 |Name19| 1 | A | 3 | 2 |
| Name20| 1 | A | 3 | 1 |Name20| 1 | A | 3 | 2 |
Where
- Nam1= Name in Semester 1
- CRDT1= Credit in Semester 1
- GRD1= Grade in Semester 1
- Year1= Year in Semester 1
- Semer1 = Semester in Semester 1
- Nam2= Name in Semester 2
- CRDT2= Credit in Semester 2
- GRD2= Grade in Semester 2
- Year2= Year in Semester 2
- Semer2 = Semester in Semester 2
Please go to this URL to test this SQL: http://sqlfiddle.com/#!3/196c6/1
How Can I create SQL to make output like this?
select
s1.Name as nam1, s1.credit as crdt1, s1.Year as year1, s1.semester as semer1,
s2.Name as nam2, s2.credit as crdt2, s2.Year as year2, s2.semester as semer2
from
(select *, ROW_NUMBER() over (partition by year order by name) rn from myTable where semester=1 ) s1
full outer join
(select *, ROW_NUMBER() over (partition by year order by name) rn from myTable where semester=2 ) s2
on s1.year = s2.year
and s1.rn = s2.rn
I don't like doing an outer join, when a simple group by is sufficient:
select max(case when semester = 1 then Name end) as name1,
max(case when semester = 1 then credit end) as credit1,
max(case when semester = 1 then year end) as year1,
max(case when semester = 1 then semester end) as semester1,
max(case when semester = 2 then Name end) as name2,
max(case when semester = 2 then credit end) as credit2,
max(case when semester = 2 then year end) as year2,
max(case when semester = 2 then semester end) as semester2
from (select t.*,
row_number() over (partition by semester order by name) as rownum
from t
) t2
group by rownum
order by rownum
select Name,credit, grade, year,semester from myTable
group by semester,year, Name,credit, grade;
now we have to make a dynamic query with this previous query:
create as temporary table as there are semster first
create dynamically a select query with all fields of all semester table in a loop:
foreach temporary table concat all fields of this table in select query
and add construct label field with semester value of this table
and add temporary table with union
'select' + #tbls1.fieldName + ',' + ... + + #tbls2.fieldName +

MySQL: Pivot + Counting

I need help with a SQL that will convert this table:
===================
| Id | FK | Status|
===================
| 1 | A | 100 |
| 2 | A | 101 |
| 3 | B | 100 |
| 4 | B | 101 |
| 5 | C | 100 |
| 6 | C | 101 |
| 7 | A | 102 |
| 8 | A | 102 |
| 9 | B | 102 |
| 10 | B | 102 |
===================
to this:
==========================================
| FK | Count 100 | Count 101 | Count 102 |
==========================================
| A | 1 | 1 | 2 |
| B | 1 | 1 | 2 |
| C | 1 | 1 | 0 |
==========================================
I can so simple counts, etc., but am struggling trying to pivot the table with the information derived. Any help is appreciated.
Use:
SELECT t.fk,
SUM(CASE WHEN t.status = 100 THEN 1 ELSE 0 END) AS count_100,
SUM(CASE WHEN t.status = 101 THEN 1 ELSE 0 END) AS count_101,
SUM(CASE WHEN t.status = 102 THEN 1 ELSE 0 END) AS count_102
FROM TABLE t
GROUP BY t.fk
use:
select * from
(select fk,fk as fk1,statusFK from #t
) as t
pivot
(COUNT(fk1) for statusFK IN ([100],[101],[102])
) AS pt
Just adding a shortcut to #OMG's answer.
You can eliminate CASE statement:
SELECT t.fk,
SUM(t.status = 100) AS count_100,
SUM(t.status = 101) AS count_101,
SUM(t.status = 102) AS count_102
FROM TABLE t
GROUP BY t.fk