PostgreSQL grouping error with Rails - sql

I have the following query:
SELECT
EXTRACT (
HOUR
FROM
interventions.created_at :: TIMESTAMP
) AS DATE,
COUNT (interventions. ID) AS total
FROM
"interventions"
INNER JOIN medical_records ON (
(
medical_records.medical_recordable_type = 'Intervention'
)
AND (
medical_records.medical_recordable_id = interventions. ID
)
)
INNER JOIN patients ON (
patients. ID = medical_records.patient_id
)
WHERE
(
interventions.created_at BETWEEN '2011-11-10 00:00:00'
AND '2014-11-10 00:00:00'
)
AND (
medical_records.hospitalization = FALSE
)
AND (
patients.birth_date BETWEEN '1892-12-31 23:50:39'
AND '2013-12-31 22:59:59'
)
GROUP BY
DATE
ORDER BY
interventions. ID DESC,
DATE ASC
And I get the following error:
PG::GroupingError: ERROR: column "interventions.id" must appear in the GROUP BY clause or be used in an aggregate function
Here is the relevant part of my code :
query = query.select("EXTRACT(HOUR FROM interventions.created_at::timestamp) AS date, COUNT(interventions.id) AS total")
query = query.group("EXTRACT(HOUR FROM interventions.created_at::timestamp)")
query = query.order("EXTRACT(HOUR FROM interventions.created_at::timestamp) ASC")
I don't understand because the column "interventions.id" is used in the COUNT() function inside the select.
Any idea on how to resolve this issue?
Thank you.

Remove interventions_id from ORDER BY clause.

Related

Query error: Column name ICUSTAY_ID is ambiguous. Using multiple subqueries in BigQuery

Hi, I receive the following query error "Query error: Column name ICUSTAY_ID is ambiguous" referred to the third last line of code (see the following code). Please can you help me? Thank you so much!
I am an SQL beginner..
WITH t AS
(
SELECT
*
FROM
(
SELECT *,
DATETIME_DIFF(CHARTTIME, INTIME, MINUTE) AS pi_recorded
FROM
(
SELECT
*
FROM
(
SELECT * FROM
(SELECT i.SUBJECT_ID, p.dob, i.hadm_id, p.GENDER, a.ETHNICITY, a.ADMITTIME, a.INSURANCE, i.ICUSTAY_ID,
i.DBSOURCE, i.INTIME, DATETIME_DIFF(a.ADMITTIME, p.DOB, DAY) AS age,
CASE
WHEN DATETIME_DIFF(a.ADMITTIME, p.DOB, DAY) <= 32485
THEN 'adult'
WHEN DATETIME_DIFF(a.ADMITTIME, p.DOB, DAY) > 32485
then '>89'
END AS age_group
FROM `project.mimic3.ICUSTAYS` AS i
INNER JOIN `project.mimic3.PATIENTS` AS p ON i.SUBJECT_ID = p.SUBJECT_ID
INNER JOIN `project.mimic3.ADMISSIONS` AS a ON i.HADM_ID = a.HADM_ID)
WHERE age >= 6570
) AS t1
LEFT JOIN
(
SELECT ITEMID, ICUSTAY_ID, CHARTTIME, VALUE, FROM `project.mimic3.CHARTEVENTS`
WHERE ITEMID = 551 OR ITEMID = 552 OR ITEMID = 553 OR ITEMID = 224631
OR ITEMID = 224965 OR ITEMID = 224966
) AS t2
ON t1.ICUSTAY_ID = t2.ICUSTAY_ID
)
)
WHERE ITEMID IN (552, 553, 224965, 224966) AND pi_recorded <= 1440
)
SELECT ICUSTAY_ID #### Query error: Column name ICUSTAY_ID is ambiguous
FROM t
GROUP BY ICUSTAY_ID;
Both t1 and t2 have a column called ICUSTAY_ID. When you join them together into a single dataset you end up with 2 columns with the same name - which obviously can't work as there would be no way of uniquely identify each column.
You need to alias these columns in you code or not include one or the other if you don't need both

Use of MAX function in SQL query to filter data

The code below joins two tables and I need to extract only the latest date per account, though it holds multiple accounts and history records. I wanted to use the MAX function, but not sure how to incorporate it for this case. I am using My SQL server.
Appreciate any help !
select
PROP.FileName,PROP.InsName, PROP.Status,
PROP.FileTime, PROP.SubmissionNo, PROP.PolNo,
PROP.EffDate,PROP.ExpDate, PROP.Region,
PROP.Underwriter, PROP_DATA.Data , PROP_DATA.Label
from
Property.dbo.PROP
inner join
Property.dbo.PROP_DATA on Property.dbo.PROP.FileID = Actuarial.dbo.PROP_DATA.FileID
where
(PROP_DATA.Label in ('Occupancy' , 'OccupancyTIV'))
and (PROP.EffDate >= '42278' and PROP.EffDate <= '42643')
and (PROP.Status = 'Bound')
and (Prop.FileTime = Max(Prop.FileTime))
order by
PROP.EffDate DESC
Assuming your DBMS supports windowing functions and the with clause, a max windowing function would work:
with all_data as (
select
PROP.FileName,PROP.InsName, PROP.Status,
PROP.FileTime, PROP.SubmissionNo, PROP.PolNo,
PROP.EffDate,PROP.ExpDate, PROP.Region,
PROP.Underwriter, PROP_DATA.Data , PROP_DATA.Label,
max (PROP.EffDate) over (partition by PROP.PolNo) as max_date
from Actuarial.dbo.PROP
inner join Actuarial.dbo.PROP_DATA
on Actuarial.dbo.PROP.FileID = Actuarial.dbo.PROP_DATA.FileID
where (PROP_DATA.Label in ('Occupancy' , 'OccupancyTIV'))
and (PROP.EffDate >= '42278' and PROP.EffDate <= '42643')
and (PROP.Status = 'Bound')
and (Prop.FileTime = Max(Prop.FileTime))
)
select
FileName, InsName, Status, FileTime, SubmissionNo,
PolNo, EffDate, ExpDate, Region, UnderWriter, Data, Label
from all_data
where EffDate = max_date
ORDER BY EffDate DESC
This also presupposes than any given account would not have two records on the same EffDate. If that's the case, and there is no other objective means to determine the latest account, you could also use row_numer to pick a somewhat arbitrary record in the case of a tie.
Using straight SQL, you can use a self-join in a subquery in your where clause to eliminate values smaller than the max, or smaller than the top n largest, and so on. Just set the number in <= 1 to the number of top values you want per group.
Something like the following might do the trick, for example:
select
p.FileName
, p.InsName
, p.Status
, p.FileTime
, p.SubmissionNo
, p.PolNo
, p.EffDate
, p.ExpDate
, p.Region
, p.Underwriter
, pd.Data
, pd.Label
from Actuarial.dbo.PROP p
inner join Actuarial.dbo.PROP_DATA pd
on p.FileID = pd.FileID
where (
select count(*)
from Actuarial.dbo.PROP p2
where p2.FileID = p.FileID
and p2.EffDate <= p.EffDate
) <= 1
and (
pd.Label in ('Occupancy' , 'OccupancyTIV')
and p.Status = 'Bound'
)
ORDER BY p.EffDate DESC
Have a look at this stackoverflow question for a full working example.
Not tested
with temp1 as
(
select foo
from bar
whre xy = MAX(xy)
)
select PROP.FileName,PROP.InsName, PROP.Status,
PROP.FileTime, PROP.SubmissionNo, PROP.PolNo,
PROP.EffDate,PROP.ExpDate, PROP.Region,
PROP.Underwriter, PROP_DATA.Data , PROP_DATA.Label
from Actuarial.dbo.PROP
inner join temp1 t
on Actuarial.dbo.PROP.FileID = t.dbo.PROP_DATA.FileID
ORDER BY PROP.EffDate DESC

ORACLE SQL equivalent to given mysql query

Hi I am stuck on conerting this query from mysql to oracle as oracle create problems in subquery order by. Query is:
SELECT bt_charges.bt_setup_id, bt_setups.name, IFNULL(bt_charges.charges_for,'OPD') as charges_for_vals, bt_charges.nc_applicable,bt_charges.unit_value,bt_charges.taxtype_id, bt_charges.id, bt_charges.amount, bt_charges.effective_date
FROM bt_setups JOIN bt_charges ON ( bt_charges.bt_setup_id = bt_setups.id AND
bt_charges.id = (SELECT id
FROM bt_charges ilaba
WHERE IFNULL(ilaba.charges_for,'OPD') = IFNULL(bt_charges.charges_for,'OPD')
AND ilaba.bt_setup_id= bt_setups.id AND ilaba.effective_date <= '2014-11-10'
AND ilaba.insprovider_id IS NULL AND ilaba.deleted=0
ORDER BY ilaba.effective_date DESC, ilaba.date_entered DESC
LIMIT 1))
WHERE bt_setups.status='Active' AND bt_setups.deleted=0
AND bt_charges.insprovider_id IS NULL
ORDER BY bt_setups.name, charges_for ASC
Here, bt_setups ( name, description ) is service provided and
bt_charges (effective_date date, date_entered datetime, charger_for char, bt_setup_id foreign key(bt_setups), insprovider_id foreign key(insproviders) ) contains charges for service applicable from effective_date, insprovider wise
SELECT bc.bt_setup_id, bs.name,
NVL(bc.charges_for,'OPD') as charges_for_vals,
bc.nc_applicable, bc.unit_value, bc.taxtype_id,
bc.id, bc.amount, bc.effective_date
FROM bt_setups bs JOIN bt_charges bc ON ( bc.bt_setup_id = bs.id AND
bc.id = (SELECT id FROM
(SELECT ilaba.id, ilaba.bt_setup_id
FROM bt_charges ilaba
WHERE NVL(ilaba.charges_for,'OPD') = NVL(bc.charges_for,'OPD')
AND ilaba.effective_date <= TO_DATE('2014-11-10', 'YYYY-MM-DD')
AND ilaba.insprovider_id IS NULL AND ilaba.deleted=0
ORDER BY ilaba.effective_date DESC, ilaba.date_entered DESC)
WHERE bt_setup_id = bs.id AND ROWNUM = 1
))
WHERE bs.status='Active' AND bs.deleted=0
AND bc.insprovider_id IS NULL
ORDER BY bs.name, charges_for ASC;
IFNULL -> NVL
'2014-11-10' -> TO_DATE('2014-11-10', 'YYYY-MM-DD') - I suppose ilaba.effective_date has DATE type
LIMIT 1 -> order by in the subquery + rownum=1 in the parent query

ORA-00936: missing expression oracle

I have this query
SELECT DAL_ROWNOTABLE.DAL_ID FROM
(
SELECT ticket.id AS "DAL_ID", ROWNUMBER ( Order By ticket.id ) AS "DAL_ROWNUMBER"
FROM ticket_table ticket
WHERE ( ticket.type = N'I' )
AND
(
ticket.tenant IS NULL OR ticket.tenant IN
(
SELECT * FROM
(
SELECT tenant_group_member.tenant_id
FROM tenant_group_member
WHERE tenant_group_member.tenant_group = HEXTORAW('30B0716FEB5F4E4BB82A7B7AA3A1A42C')
ORDER BY ticket.id
)
)
)
) DAL_ROWNOTABLE
WHERE DAL_ROWNOTABLE.DAL_ROWNUMBER BETWEEN 1 AND 21
What is the problem with the allow query that is throwing ORA-00936 missing expression? anyone? Any help will be appreciated...Error thrown at column:80 which is at the beginning of first order by:
ORA-00936 usually indicates a syntax error.
ROWNUMBER is not an Oracle function. Unless you have a user-defined function of that name I suspect the function you're looking for is ROW_NUMBER().
Your query can be much simplified. It has things like extra layers of subqueries and an unnecessary order by in an in subquery. What you want to do with rownumber you can do with just rownum:
SELECT DAL_ROWNOTABLE.DAL_ID
FROM (SELECT ticket.id AS "DAL_ID"
FROM ticket_table ticket
WHERE (ticket.type = N'I' ) AND
(ticket.tenant IS NULL OR
ticket.tenant IN (SELECT tgm.tenant_id
FROM tenant_group_member tgm
WHERE tgm.tenant_group = HEXTORAW('30B0716FEB5F4E4BB82A7B7AA3A1A42C')
)
)
ORDER BY ticket.id
) DAL_ROWNOTABLE
WHERE rownum <= 21;

Joining two SELECT statements using Outer Join with multiple alias

I have a complicated select statement that when it is executed, I give it a date or date range I want and the output comes out. The problem is I don't know how to join the same SQL statement with the first Statement having 1 date range and the second statement having another data range. Example below:
When I execute the select statement, I choose for the Month of November:
EMPLID NAME Current_Gross_Hours(November)
When I execute the select statement again, I choose from January to November:
EMPLID NAME Year_To_Date_Hours(January - November)
What I want:
EMPLID NAME Current_Gross_Hours(November) Year_To_Date_Hours(January - November)
The SQL Select statement runs correctly if execute by themselves. But I don't know how to join them.
Here is the SQL code that I want to write, but I don't know how to write the SQL statement correctly. Any help or direction is greatly appreciated.
(SELECT DISTINCT
SUM("PSA"."AL_HOURS") AS "Current Gross Hours", "PSJ"."EMPLID","PSP"."NAME"
FROM
"PS_JOB" "PSJ", "PS_EMPLOYMENT" "PSE", "PS_PERSONAL_DATA" "PSP", "PS_AL_CHK_HRS_ERN" "PSA"
WHERE
((("PSA"."CHECK_DT" = TO_DATE('2011-11-01', 'YYYY-MM-DD')) AND
("PSJ"."PAYGROUP" = 'SK2') AND
(("PSJ"."EFFSEQ"= (
SELECT MAX("INNERALIAS"."EFFSEQ")
FROM "PS_JOB" INNERALIAS
WHERE "INNERALIAS"."EMPL_RCD_NBR" = "PSJ"."EMPL_RCD_NBR"
AND "INNERALIAS"."EMPLID" = "PSJ"."EMPLID"
AND "INNERALIAS"."EFFDT" = "PSJ"."EFFDT")
AND
"PSJ"."EFFDT" = (
SELECT MAX("INNERALIAS"."EFFDT")
FROM "PS_JOB" INNERALIAS
WHERE "INNERALIAS"."EMPL_RCD_NBR" = "PSJ"."EMPL_RCD_NBR"
AND "INNERALIAS"."EMPLID" = "PSJ"."EMPLID"
AND "INNERALIAS"."EFFDT" <= SYSDATE)))))
AND
("PSJ"."EMPLID" = "PSE"."EMPLID" ) AND ("PSJ"."EMPLID" = "PSP"."EMPLID" ) AND ("PSJ"."FILE_NBR" = "PSA"."FILE_NBR" ) AND ("PSJ"."PAYGROUP" = "PSA"."PAYGROUP" ) AND ("PSE"."EMPLID" = "PSP"."EMPLID" )
GROUP BY
"PSJ"."EMPLID", "PSP"."NAME"
) AS "Q1"
LEFT JOIN
(SELECT DISTINCT
SUM("PSA"."AL_HOURS") AS "YEAR_TO_DATE Gross Hours", "PSJ"."EMPLID"
FROM
"PS_JOB" "PSJ", "PS_EMPLOYMENT" "PSE", "PS_PERSONAL_DATA" "PSP", "PS_AL_CHK_HRS_ERN" "PSA"
WHERE
((("PSA"."CHECK_DT" BETWEEN TO_DATE('2011-01-01', 'YYYY-MM-DD') AND TO_DATE('2011-11-01', 'YYYY-MM-DD')) AND
("PSJ"."PAYGROUP" = 'SK2') AND
(("PSJ"."EFFSEQ"= (
SELECT MAX("INNERALIAS"."EFFSEQ")
FROM "PS_JOB" INNERALIAS
WHERE "INNERALIAS"."EMPL_RCD_NBR" = "PSJ"."EMPL_RCD_NBR"
AND "INNERALIAS"."EMPLID" = "PSJ"."EMPLID"
AND "INNERALIAS"."EFFDT" = "PSJ"."EFFDT")
AND
"PSJ"."EFFDT" = (
SELECT MAX("INNERALIAS"."EFFDT")
FROM "PS_JOB" INNERALIAS
WHERE "INNERALIAS"."EMPL_RCD_NBR" = "PSJ"."EMPL_RCD_NBR"
AND "INNERALIAS"."EMPLID" = "PSJ"."EMPLID"
AND "INNERALIAS"."EFFDT" <= SYSDATE)))))
AND
("PSJ"."EMPLID" = "PSE"."EMPLID" ) AND ("PSJ"."EMPLID" = "PSP"."EMPLID" ) AND ("PSJ"."FILE_NBR" = "PSA"."FILE_NBR" ) AND ("PSJ"."PAYGROUP" = "PSA"."PAYGROUP" ) AND ("PSE"."EMPLID" = "PSP"."EMPLID" )
GROUP BY
"PSJ"."EMPLID"
) AS "Q2"
ON "Q1"."EMPLID"="Q2"."EMPLID"
ORDER BY
"Q1"."NAME"
You are missing a SELECT ... FROM at the start. The AS keyword only works when creating column aliases, not query block aliases. Quotation marks are only necessary for case-sensitive column names - they don't look incorrect in your example but they frequently cause mistakes.
SELECT Q1.NAME, ...
FROM
(
SELECT ...
) Q1
JOIN
(
SELECT ...
) Q2
ON Q1.EMPLID=Q2.EMPLID
ORDER BY Q1.NAME