I can't group my CourseCode Column properly using this code, can you help me how to group the CourseCode and SUM how many BSIT and ICT borrowed a book in specific month.
use CLS
Select C.CourseCode,
Case When DATENAME(MONTH, T.DateBorrowed) = 'January' then SUM(C.CourseCode) else 0 end as January,
Case When DATENAME(MONTH, T.DateBorrowed) = 'February' then SUM(C.CourseCode) else 0 end as February,
Case When DATENAME(MONTH, T.DateBorrowed) = 'March' then SUM(C.CourseCode) else 0 end as March
From TBL_Transactions T left outer join (TBL_Member M left outer join TBL_Course C ON M.CourseID = C.CourseID) ON T.MemberIDNo = M.MemberIDNo
Group by C.CourseCode, T.DateBorrowed!
Try this...
SELECT C.CourseCode, DATENAME(MONTH, T.DateBorrowed), SUM(C.CourseCode)
FROM TBL_Transactions T LEFT OUTER JOIN
(TBL_Member M LEFT OUTER JOIN TBL_Course C ON M.CourseID = C.CourseID)
ON T.MemberIDNo = M.MemberIDNo
GROUP BY C.CourseCode, DATENAME(MONTH, T.DateBorrowed)!
Related
This works:
SELECT DISTINCT
"public".visit.visit_id,
"public".visit.visit_name,
"public".visit.visit_admit_date,
"public".visit.visit_disch_date,
"public".visit.visit_stay_type,
"public".visit.visit_ins,
"public".ip_visit_1.ipv1_room,
"public".ip_visit_1.ipv1_ad_init,
CASE WHEN (SELECT digital_signature_images.dsigimg_acct FROM digital_signature_images where "public".visit.visit_id = digital_signature_images.dsigimg_acct AND digital_signature_images.dsigimg_title = 'IMPORTANT LETTER FROM MEDICARE') IS NOT NULL THEN 'YES'
WHEN (SELECT patient_images.patimg_acct FROM patient_images where visit.visit_id = patient_images.patimg_acct AND patient_images.patimg_title = 'IMPORTANT LETTER FROM MEDICARE') IS NOT NULL THEN 'YES' ELSE 'NOT ON FILE' END AS IMFM_ON_FILE
FROM
"public".digital_signature_images
INNER JOIN "public".visit ON "public".visit.visit_id = "public".digital_signature_images.dsigimg_acct
INNER JOIN "public".ip_visit_1 ON "public".visit.visit_id = "public".ip_visit_1.ipv1_num
INNER JOIN "public".patient_images ON "public".patient_images.patimg_acct = "public".visit.visit_id
WHERE
"public".visit.visit_ins LIKE 'M%' AND
"public".visit.visit_stay_type = '1' AND
"public".visit.visit_disch_date = '2022-07-01'
ORDER BY
"public".ip_visit_1.ipv1_room
When I try to do the previous month only in the WHERE portion, I get told "More than one row returned by a subquery used as an expression:
SELECT DISTINCT
"public".visit.visit_id,
"public".visit.visit_name,
"public".visit.visit_admit_date,
"public".visit.visit_disch_date,
"public".visit.visit_stay_type,
"public".visit.visit_ins,
"public".ip_visit_1.ipv1_room,
"public".ip_visit_1.ipv1_ad_init,
CASE WHEN (SELECT digital_signature_images.dsigimg_acct FROM digital_signature_images where "public".visit.visit_id = digital_signature_images.dsigimg_acct AND digital_signature_images.dsigimg_title = 'IMPORTANT LETTER FROM MEDICARE') IS NOT NULL THEN 'YES'
WHEN (SELECT patient_images.patimg_acct FROM patient_images where visit.visit_id = patient_images.patimg_acct AND patient_images.patimg_title = 'IMPORTANT LETTER FROM MEDICARE') IS NOT NULL THEN 'YES' ELSE 'NOT ON FILE' END AS IMFM_ON_FILE
FROM
"public".digital_signature_images
INNER JOIN "public".visit ON "public".visit.visit_id = "public".digital_signature_images.dsigimg_acct
INNER JOIN "public".ip_visit_1 ON "public".visit.visit_id = "public".ip_visit_1.ipv1_num
INNER JOIN "public".patient_images ON "public".patient_images.patimg_acct = "public".visit.visit_id
WHERE
"public".visit.visit_ins LIKE 'M%' AND
"public".visit.visit_stay_type = '1' AND
ip_visit_1.ipv1_dis_date >= DATE_TRUNC('MONTH', CURRENT_DATE - INTERVAL '1 MONTH') AND
ip_visit_1.ipv1_dis_date < DATE_TRUNC('MONTH', CURRENT_DATE)
ORDER BY
"public".ip_visit_1.ipv1_room
How can I return the previous month?
use EXISTS (subquery) to determine if a subquery returns at least one row. It returns a boolean, so you can put it directly after the WHEN.
I am using the following query in PostgreSQL:
SELECT
pegawai_nama,
COUNT(operasi_operator_dokter) AS total,
CASE tindakan_golongan WHEN 'KECIL' THEN SUM(tariftindakan_biaya_alkes)
ELSE 0
END AS KECIL,
CASE tindakan_golongan WHEN 'BESAR' THEN SUM(tariftindakan_biaya_alkes)
ELSE 0
END AS BESAR,
CASE tindakan_golongan WHEN 'KHUSUS' THEN SUM(tariftindakan_biaya_alkes
ELSE 0
END AS SEDANG
FROM
t_operasi
LEFT JOIN m_pasien On t_operasi.operasi_pasien_norm = m_pasien.pasien_norm
LEFT JOIN t_pendaftaran on t_operasi.operasi_pendaftaran_id = t_pendaftaran.pendaftaran_id
LEFT JOIN m_tindakan ON t_operasi.operasi_tindakan_id = m_tindakan.tindakan_id
LEFT JOIN m_tarif_tindakan ON m_tindakan.tindakan_id = m_tarif_tindakan.m_tindakan_id
LEFT JOIN m_pegawai ON cast(m_pegawai.pegawai_id as varchar(10)) = t_operasi.operasi_operator_dokter
LEFT JOIN t_diagnosa_pasien ON t_diagnosa_pasien.t_pendaftaran_id = t_pendaftaran.pendaftaran_id
LEFT JOIN m_icd ON m_icd.icd_id = t_diagnosa_pasien.m_icd_id
WHERE operasi_id IS NOT NULL AND tindakan_golongan IN ('KECIL', 'BESAR', 'KHUSUS', 'SEDANG', '')
GROUP BY pegawai_nama, tindakan_golongan;
However, the result below is not what I am after:
Instead I would like the following result:
pegawai_nama total kecil besar sedang khusus
DR. JOKO TRIYONO, SPM 2 189000 0 909700 0
DR. DJOHAR ANWAR 3 567000 0 0 0
Just have this as a nested query, and group it again:
select pegawai_nama, sum(total) as total , sum(kecil) as kecil, sum(besar) as besar, sum(sedang) as sedang
from (
-- insert your query here
) sub
group by pegawai_nama
Try taking out the "tindakan_golongan" column from the GROUP BY.
This is my new code (based on Georgi Raychev's answer):
SELECT
sub.pegawai_nama,
sum(sub.total) as total,
sum(sub.kecil) as kecil,
sum(sub.besar) as besar,
sum(sub.sedang) as sedang,
sum(sub.khusus) as khusus
FROM (
SELECT
pegawai_nama,
COUNT(operasi_operator_dokter) AS total,
CASE tindakan_golongan WHEN 'KECIL' THEN SUM(tariftindakan_biaya_alkes +
tariftindakan_biaya_cover +tariftindakan_biaya)
ELSE 0
END AS kecil,
CASE tindakan_golongan WHEN 'BESAR' THEN SUM(tariftindakan_biaya_alkes +
tariftindakan_biaya_cover +tariftindakan_biaya)
ELSE 0
END AS besar,
CASE tindakan_golongan WHEN 'KHUSUS' THEN SUM(tariftindakan_biaya_alkes +
tariftindakan_biaya_cover +tariftindakan_biaya)
ELSE 0
END AS khusus,
CASE tindakan_golongan WHEN 'SEDANG' THEN SUM(tariftindakan_biaya_alkes +
tariftindakan_biaya_cover +tariftindakan_biaya)
ELSE 0
END AS sedang
FROM
t_operasi
LEFT JOIN m_pasien On t_operasi.operasi_pasien_norm = m_pasien.pasien_norm
LEFT JOIN t_pendaftaran on t_operasi.operasi_pendaftaran_id = t_pendaftaran.pendaftaran_id
LEFT JOIN m_tindakan ON t_operasi.operasi_tindakan_id = m_tindakan.tindakan_id
LEFT JOIN m_tarif_tindakan ON m_tindakan.tindakan_id = m_tarif_tindakan.m_tindakan_id
LEFT JOIN m_pegawai ON cast(m_pegawai.pegawai_id as varchar(10)) = t_operasi.operasi_operator_dokter
LEFT JOIN t_diagnosa_pasien ON t_diagnosa_pasien.t_pendaftaran_id = t_pendaftaran.pendaftaran_id
LEFT JOIN m_icd ON m_icd.icd_id = t_diagnosa_pasien.m_icd_id
WHERE operasi_id IS NOT NULL
GROUP BY pegawai_nama, tindakan_golongan
) AS sub
GROUP BY sub.pegawai_nama
;
And this is the result:
New Result
I have written a query in two models, but I can't figure out why the second query returns a greater number than the first one; while the number that the first one, COUNT(DISTINCT...) returns is correct:
WITH types(id) AS (VALUES('{1, 4, 5, 3}'::INTEGER[])),
date_gen64 AS
(
SELECT CAST (generate_series(date '10/1/2017', date '11/15/2017', interval
'1 day') AS date) as days ORDER BY days)
SELECT cl.class_date AS c_date,
count(DISTINCT (CASE WHEN co.id = 1 THEN p.id END)),
count(DISTINCT (CASE WHEN co.id = 2 THEN p.id END))
FROM person p
JOIN envelope e ON e.personID = p.id
JOIN "class" cl on cl.id = p.classID
JOIN course co ON co.id = cl.course_id AND co.id = 1
JOIN types ON cr.type_id = ANY (types.id)
RIGHT JOIN date_gen64 dg ON dg.days = cl.class_date
GROUP BY cl.class_date
ORDER BY cl.class_date
The above query returns 26 but following query returns 27!
The reason why I rewrote it with SUM is that the first query
was too slow. But my question is that why the second one counts more?
WITH types(id) AS (VALUES('{1, 4, 5, 3}'::INTEGER[]))
SELECT tmpcl.days,
SUM(CASE WHEN tmp80.course_id = 1 THEN 1
ELSE 0 END),
SUM(CASE WHEN tmp80.course_id = 2 THEN 1
ELSE 0 END)
FROM (
SELECT CAST (generate_series(date '10/1/2017', date '11/15/2017',
interval '1 day') AS date) as days ORDER BY days) tmpcl
LEFT JOIN (
SELECT DISTINCT p.id AS "person_id",
cl.class_date AS c_date,
co.id AS "course_id"
FROM person p
JOIN envelope e ON e.personID = p.id
JOIN "class" cl on cl.id = p.classID
JOIN course co ON co.id = cl.course_id
JOIN types ON cr.type_id = ANY (types.id)
WHERE co.id IN ( 1 , 2 )
) tmp80 ON tmpcl.days = tmp80.class_date
GROUP BY tmpcl.days
ORDER BY tmpcl.days
You can theoretically have multiple people enrolled in the same class on the same day. Indeed that would seem to be the main point of having classes. So each time there are multiple people assigned to the same class on the same day you can have a higher count than you would in your first query. Does that make sense?
You don't appear to be using p.id in that inner query so simply remove it and your counts should match.
WITH types(id) AS (VALUES('{1, 4, 5, 3}'::INTEGER[]))
SELECT tmpcl.days,
SUM(CASE WHEN tmp80.course_id = 1 THEN 1
ELSE 0 END),
SUM(CASE WHEN tmp80.course_id = 2 THEN 1
ELSE 0 END)
FROM (
SELECT CAST (generate_series(date '10/1/2017', date '11/15/2017',
interval '1 day') AS date) as days ORDER BY days) tmpcl
LEFT JOIN (
SELECT DISTINCT cl.class_date AS c_date,
co.id AS "course_id"
FROM person p
JOIN envelope e ON e.personID = p.id
JOIN "class" cl on cl.id = p.classID
JOIN course co ON co.id = cl.course_id
JOIN types ON cr.type_id = ANY (types.id)
WHERE co.id IN ( 1 , 2 )
) tmp80 ON tmpcl.days = tmp80.class_date
GROUP BY tmpcl.days
ORDER BY tmpcl.days
SELECT
cu.user_id,
cu.gender,
CASE WHEN cu.looking_for_gender = cu.gender THEN 1 ELSE 0 END AS
sexual_orientation,
os_name,
ROUND((DATE(NOW()) - cu.birthdate)/365.25) AS user_age,
SUM(dsb.likes) AS likes,
SUM(dsb.dislikes) AS dislikes,
SUM(dsb.blocks) AS blocks,
SUM(dsb.matches) AS matches,
SUM(dsb.received_likes) AS received_likes,
SUM(dsb.received_dislikes) AS received_dislikes,
SUM(dsb.received_blocks) AS received_blocks,
CASE WHEN cu.status = 'default' THEN 1 ELSE 0 END AS recall_case,
CASE WHEN cu.status = 'default' THEN extract(epoch from
cu.last_activity - cu.updated_time)/86400 ELSE 0 END AS
recall_retention
FROM ( SELECT stats.core_users cu
LEFT JOIN yay.daily_swipes_by_users dsb ON (dsb.user_id = cu.user_id)
WHERE cu.user_id = '1' GROUP BY 1) e1
LEFT JOIN LATERAL (SELECT cd.os_name FROM stats.core_devices cd WHERE
e1.user_id = cd.user_id ORDER BY cd.updated_time DESC LIMIT 1) e2
ON TRUE;
Current Error Code:
ERROR: syntax error at or near "LEFT"
LINE 18: LEFT JOIN yay.daily_swipes_by_users dsb ON (dsb.user_id = cu...
^
The supplied query would fail in many ways, the following might work I hope, but as you can see this drops a great deal of other columns in the process
SELECT
e1.user_id
, e1.cu
, e2.os_name
FROM (
SELECT stats.core_users cu, cu.user_id
LEFT JOIN yay.daily_swipes_by_users dsb ON (dsb.user_id = cu.user_id)
WHERE cu.user_id = '1'
GROUP BY stats.core_users cu, cu.user_id
) e1
LEFT JOIN LATERAL(
SELECT cd.os_name
FROM stats.core_devices cd
WHERE e1.user_id = cd.user_id
ORDER BY cd.updated_time DESC
LIMIT 1) e2 ON TRUE
;
SELECT
cu.user_id,
cu.gender,
CASE WHEN cu.looking_for_gender = cu.gender THEN 1 ELSE 0 END AS sexual_orientation,
e2.os_name,
ROUND((DATE(NOW()) - cu.birthdate)/365.25) AS user_age,
CASE WHEN cu.status = 'default' THEN 1 ELSE 0 END AS recall_case,
CASE WHEN cu.status = 'default' THEN extract(epoch from cu.last_activity - cu.updated_time)/86400 ELSE 0 END AS recall_retention,
SUM(dsb.likes) AS likes,
SUM(dsb.dislikes) AS dislikes,
SUM(dsb.blocks) AS blocks,
SUM(dsb.matches) AS matches,
SUM(dsb.received_likes) AS received_likes,
SUM(dsb.received_dislikes) AS received_dislikes,
SUM(dsb.received_blocks) AS received_blocks
FROM
stats.core_users cu
LEFT JOIN yay.daily_swipes_by_users dsb ON (dsb.user_id = cu.user_id)
LEFT JOIN LATERAL (SELECT cd.os_name FROM stats.core_devices cd WHERE cu.user_id = cd.user_id ORDER BY cd.updated_time DESC LIMIT 1) e2
ON TRUE
WHERE cu.user_id = '1'
GROUP BY 1,2,3,4,5,6,7
;
This works.
I want to ask how to combine these two queries become one subquery?
select c.CustomerName, A.Qty
from Customer c join (select s.CustomerID, pd.Date, s.Qty
from Period pd join Sales s on pd.TimeID = s.TimeID) A on c.CustomerID = A.CustomerID
where #Date = A.Date
and
select sum(case when (pd.Date between '2010-03-15' and #Date) then s.Qty else 0 end) as TotalQty
from Period pd full join Sales s on pd.TimeID = s.TimeID full join Customer c on s.CustomerID = c.CustomerID
group by c.CustomerName, c.CustomerID
They should result one table contains these following columns: CustomerName, Qty, and TotalQty. I've tried many ways but they didn't work at all. Really hope your help, thanks.
Answering your question assuming you are looking at the result as one row and not "column" :
select c.CustomerName, A.Qty,(select sum(case when (pd.Date between '2010-03-15' and #Date) then s.Qty else 0 end)
from Period pd full join Sales s on pd.TimeID = s.TimeID full join Customer c on s.CustomerID = c.CustomerID
group by c.CustomerName, c.CustomerID
) as TotalQty
from Customer c join (select s.CustomerID, pd.Date, s.Qty
from Period pd join Sales s on pd.TimeID = s.TimeID) A on c.CustomerID = A.CustomerID
where #Date = A.Date
If you still want the result as a single column , google "row to column transpose"