Query with embedded CURSOR - what is the error? - sql

The following Query Works....
SELECT art.cmp_lvl,
(
CURSOR (
SELECT a.cmp_lvl,
(
CURSOR (
SELECT b.cmp_lvl_code,
b.v1 "R_ST",
b.f_name
FROM temp_data b
WHERE b.cmp_lvl = a.cmp_lvl
ORDER BY SEQ
)
) employee
FROM temp_data a
WHERE a.cmp_lvl = art.cmp_lvl
GROUP BY a.cmp_lvl
)
) g_pos_record
FROM temp_data art
WHERE art.report_name = 'EMP_REPORT'
GROUP BY cmp_lvl
ORDER BY cmp_lvl DESC;
Then I simply add another column name as shown below
SELECT art.cmp_lvl,
art.v1 /*ADDED THIS LINE, SHOWS AN ERROR IN THIS LINE */
(
CURSOR (
SELECT a.cmp_lvl,
a.v1 /*ADDED THIS LINE */
(
CURSOR (
SELECT b.cmp_lvl_code,
b.v1 "R_ST",
b.f_name
FROM temp_data b
WHERE b.cmp_lvl = a.cmp_lvl
AND b.v1 = a.v1 /*ADDED THIS LINE */
ORDER BY SEQ
)
) employee
FROM temp_data a
WHERE a.cmp_lvl = art.cmp_lvl
AND a.v1 = art.v1 /*ADDED THIS LINE */
GROUP BY a.cmp_lvl
)
) g_pos_record
FROM temp_data art
WHERE art.report_name = 'EMP_REPORT'
GROUP BY cmp_lvl
ORDER BY cmp_lvl DESC;
Error: ORA-00904: "ART", "V1": Invalid Identifier
00904. 00000 - "%s: Invalid identifier" "Cause
*Action Error at Line 2
I Cannot figure out why. The column added is in the table (for sure).

You aggregate your data to one result row per cmp_lvl (GROUP BY cmp_lvl). Then you want to show the cmp_lvl's v1. However, as there are multiple rows per cmp_lvl that you are aggregating, which row's v1 shall be shown?
Moreover, there is a comma missing after art.v1.
One solution is to decide for one v1, e.g.:
SELECT art.cmp_lvl,
MAX(art.v1),
...

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

Exception - Combining two data sets in HiveQL

I am facing Analytics Exception while having inner data sets to be combined.
Query:
Select key,days
FROM
(
Select key
FROM sls where id =14004
) AS first
JOIN
(
Select seckey ,days
FROM
(
Select seckey , MAX(opp_days) As days from sls_daily Where id=14004 Group By key
) As f
JOIN
(
Select key,est,cls,days from sls_daily Where dw_cid=14004
) As s
ON f.days = s.days AND f.key= s.key
) AS second
ON second.seckey = first.key
Exception:
AnalysisException: Syntax error in line 15: ) AS first ^ Encountered:
FIRST Expected: IDENTIFIER CAUSED BY: Exception: Syntax error
What is the reason for the error.
Try to avoid reserved words in SQL.
Try like this
Select `key`,`days`
FROM
(
Select `key`
FROM sls where id =14004
) AS `first`
JOIN
(
Select seckey ,`days`
FROM
(
Select seckey , MAX(opp_days) As `days` from sls_daily Where id=14004 Group By key
) As f
JOIN
(
Select `key`,est,cls,`days` from sls_daily Where dw_cid=14004
) As s
ON f.`days` = s.`days` AND f.`key`= s.`key`
) AS `second`
ON `second`.seckey = `first`.`key`

Trying to calculate cummulative sum in tsql

What am I doing wrong here?
The result is an error, saying:
Msg 102, Level 15, State 1, Line 3 Incorrect syntax near 'order'.
Msg 156, Level 15, State 1, Line 25 Incorrect syntax near the keyword
'as'.
select *
, Antal + Normtid as Flextid
, SUM(antal) OVER (PARTITION BY transdate ORDER BY tekst)
, x = row_number() over (partition by åruge order by tekst)
from
(
select *
,
(
select b.antal
from bi.dbo.Table_pg_FlextidsopgørelseGlUdgave b
where b.tekst = bi.dbo.Table_pg_FlextidsopgørelseGlUdgave.tekst
and b.transdate = bi.dbo.Table_pg_FlextidsopgørelseGlUdgave.transdate
and b.åruge = bi.dbo.Table_pg_FlextidsopgørelseGlUdgave.åruge
and b.type = 'Normtid'
) as Normtid
from
bi.dbo.Table_pg_FlextidsopgørelseGlUdgave
where type = 'afholdt'
and tekst = 'fs'
--and åruge = '201501'
) as data
order by tekst, transdate
Regards
Peter
It is obvious that you have inappropriate version of Sql Server. Cumulative sums with order by clause like:
SUM(antal) OVER (PARTITION BY transdate ORDER BY tekst)
are only available from Sql Server 2012+.
Actually I can reproduce those errors on Sql Server 2008:
This is on Sql Server 2012:
Notice how the error message changes.
The way you are getting data from derived table is not correct..
EX:
create table
sales
(
id int
)
insert into sales
values
(1),
(2),
(3)
derived table should always have table alias and parent table should refer using from
----this is valid
select
* from
(
select id+1 as id1
from sales
) b
--this is not valid
select
*
(select
id from sales
)b
--Above is valid when you have a subquery say
select
id,(select t1.name from table t1 where t1.id=t2.id)as custname
from table t2
coming to your question..this is not valid.I see both table types are same
select *
,
(
select b.antal
from bi.dbo.Table_pg_FlextidsopgørelseGlUdgave b
where b.tekst = bi.dbo.Table_pg_FlextidsopgørelseGlUdgave.tekst
and b.transdate = bi.dbo.Table_pg_FlextidsopgørelseGlUdgave.transdate
and b.åruge = bi.dbo.Table_pg_FlextidsopgørelseGlUdgave.åruge
and b.type = 'Normtid'
) as Normtid
from
bi.dbo.Table_pg_FlextidsopgørelseGlUdgave
where type = 'afholdt'
and tekst = 'fs'
--and åruge = '201501'
So you can write something like below
select *
, Antal + Normtid as Flextid
, SUM(antal) OVER (PARTITION BY transdate ORDER BY tekst)
, x = row_number() over (partition by åruge order by tekst)
from
(
select * from
(
select b.antal
from bi.dbo.Table_pg_FlextidsopgørelseGlUdgave b
where b.tekst = bi.dbo.Table_pg_FlextidsopgørelseGlUdgave.tekst
and b.transdate = bi.dbo.Table_pg_FlextidsopgørelseGlUdgave.transdate
and b.åruge = bi.dbo.Table_pg_FlextidsopgørelseGlUdgave.åruge
and b.type = 'Normtid'
and b.type='afholdt'
and b.tekst = 'fs'
) as Normtid
order by tekst, transdate

Join Oracle tables on an exact match, and a closest match

I am trying to join two tables of performance metrics, system stats and memory usage. Entries in these tables come in on differing time schedules. I need to join the tables by finding the exact match for the System_Name in both tables, and the closest for WRITETIME. Write time uses the systems own idea of time and is NOT a standard Oracle timestamp.
I can select the closest timestamp from one table with something like:
select "Unix_Memory"."WRITETIME", ABS ('1140408134015004' - "Unix_Memory"."WRITETIME")
as Diff from "Unix_Memory"
where "Unix_Memory"."WRITETIME" > '1140408104015004' order by Diff;
The constants there will be parameterised in my script.
However when I try to expand this into my larger query:
select "System"."System_Name", "System"."WRITETIME" as SysStamp,
from "System"
join "Unix_Memory" on "System"."System_Name" = "Unix_Memory"."System_Name"
and "Unix_Memory"."WRITETIME" = (
select Stamp from (
select "Unix_Memory"."WRITETIME" as Stamp,
ABS ( "System"."WRITETIME" - "Unix_Memory"."WRITETIME") as Diff
from "Unix_Memory" where "Unix_Memory"."WRITETIME" > '1140408104015004' and rownum = 1 order by Diff
)
)
WHERE "System"."System_Name" in ('this','that', 'more')
and "System"."WRITETIME" > '1140408124015004';
I get:
Error at Command Line:38 Column:72
Error report:
SQL Error: ORA-00904: "System"."WRITETIME": invalid identifier
00904. 00000 - "%s: invalid identifier"
I have tried a few variations, but I am not getting any closer.
You must state the System table in the inner Select as well.
select "System"."System_Name", "System"."WRITETIME" as SysStamp,
from "System"
join "Unix_Memory" on "System"."System_Name" = "Unix_Memory"."System_Name"
and "Unix_Memory"."WRITETIME" = (
select Stamp from (
select "Unix_Memory"."WRITETIME" as Stamp,
ABS ( "System"."WRITETIME" - "Unix_Memory"."WRITETIME") as Diff
from "Unix_Memory"
-- THE NEXT LINE IS MISSING IN YOUR CODE
INNER JOIN "System" ON "System.System_Name" = "Unix_Memory"."System_Name"
and "System"."WRITETIME" > '1140408124015004'
-- end of missing
where "Unix_Memory"."WRITETIME" > '1140408104015004' and rownum = 1 order by Diff
)
)
WHERE "System"."System_Name" in ('this','that', 'more')
and "System"."WRITETIME" > '1140408124015004';
Unfortunately the column names are only known in the next nesting level. So System.writetime would be known in select Stamp from ..., but no more in select "Unix_Memory"."WRITETIME" as Stamp ...
Anyhow, you would select a rather random stamp anyhow, the first Unix_Memory"."WRITETIME" > '1140408104015004' found to be precise, because rownum = 1 gets executed before order by. You will have to re-write your statement completely.
EDIT: Here is one possibility to re-write the statement using MIN/MAX KEEP:
select
s.system_name,
s.writetime as sysstamp,
min(um.id) keep (dense_rank first order by abs(s.writetime - um.writetime)) as closest_um_id
from system sys
join unix_memory um on s.system_name = um.system_name
where s.system_name in ('this','that', 'more')
and s.writetime > '1140408124015004'
and um.writetime > '1140408104015004'
group by s.system_name, s.writetime
order by s.system_name, s.writetime;
If you need more than just the ID of unix_memory then surround this with another select:
select
sy.system_name,
sy.sysstamp,
mem.*
from
(
select
s.system_name,
s.writetime as sysstamp,
min(um.id) keep (dense_rank first order by abs(s.writetime - um.writetime)) as closest_um_id
from system sys
join unix_memory um on s.system_name = um.system_name
where s.system_name in ('this','that', 'more')
and s.writetime > '1140408124015004'
and um.writetime > '1140408104015004'
group by s.system_name, s.writetime
) sy
join unix_memory mem on mem.id = sy.closest_um_id
order by sy.system_name, sy.sysstamp;

PostgreSQL grouping error with Rails

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.