sqlite query python - sql

i want to perform the below query
SELECT t1.patient_report, COUNT(*) AS cnt, t1.doctor_report, (SELECT t2.doctor_report FROM infoTable t2 WHERE t2.patient_report = t1.patient_report AND cnt > 1 LIMIT 3) AS Doctors FROM infoTable t1 WHERE t1.patient_report != 'N/A' GROUP BY t1.patient_report ORDER BY cnt DESC
but i got this error!
Result: no such column: cnt
please how can i solve the problem ?

The subquery can't access the aliased column cnt of the outer query.
But even if it did have accesss, another error would be thrown because the subquery may return more than 1 rows.
I think that you can do what you want with window functions and GROUP_CONCAT():
SELECT t.patient_report, t.cnt,
GROUP_CONCAT(doctor_report) AS Doctors
FROM (
SELECT patient_report,
doctor_report,
ROW_NUMBER() OVER (PARTITION BY patient_report) rn,
COUNT(*) OVER (PARTITION BY patient_report) cnt
FROM infoTable
WHERE patient_report <> 'N/A'
) t
WHERE t.rn <= 3 AND t.cnt > 1
GROUP BY t.patient_report, t.cnt
ORDER BY t.cnt DESC

Related

Selecting the latest order

I need to select the data of all my customers with the records displayed in the image. But I need to get the most recent record only, for example I need to get the order # E987 for John and E888 for Adam. As you can see from the example, when I do the select statement, I get all the order records.
You don't mention the specific database, so I'll answer with a generic solution.
You can do:
select *
from (
select t.*,
row_number() over(partition by name order by order_date desc) as rn
from t
) x
where rn = 1
You can use analytical function row_number.
Select * from
(Select t.*,
Row_number() over (partition by customer_id order by order_date desc) as rn
From your_table t) t
Where rn = 1
Or you can use not exists as follows:
Select *
From yoir_table t
Where not exists
(Select 1 from your_table tt
Where t.customer_id = tt.custome_id
And tt.order_date > t.order_date)
You can do it with a subquery that finds the last order date.
SELECT t.*
FROM yoir_table t
JOIN (SELECT tt.custome_id,
MAX(tt.order_date) MaxOrderDate
FROM yoir_table tt
GROUP BY tt.custome_id) AS tt
ON t.custome_id = tt.custome_id
AND t.order_date = tt.MaxOrderDate

rownum is not returning anything even if without rownum a record is shown

I have a select statement in DB2 that returns a record when executed however if I add a restriction like rownum >=1 and rownum <=2 no record is being returned.
Select statement:
When I try with:
SELECT person.ID, person.SEX, person.BYEAR, person.BMONTH,
person.BDAY
FROM MIGRATION.LEGALPERSON person
JOIN MIGRATION.LEGALPARTNER part ON person.ID = part.ID
WHERE person.STATUS = 'ACTIVE'
one record is returned.
And with the
SELECT person.ID, person.SEX, person.BYEAR, person.BMONTH,
person.BDAY
FROM MIGRATION.LEGALPERSON person
JOIN MIGRATION.LEGALPARTNER part ON person.ID = part.ID
WHERE person.STATUS = 'ACTIVE' and person.ROWNUM >= 1 and person.ROWNUM <= 2
no record is returned.
What could be the root cause?
You can't use rownum that way (see documentation, https://docs.oracle.com/cd/B19306_01/server.102/b14200/pseudocolumns009.htm):
Conditions testing for ROWNUM values greater than a positive integer are always false
If you want to do something like that, consider using row_number analytic function, e.g.
with temp as
(select some_column,
row_number() over (order by date_value) rn
from your_table
)
select *
from temp
where rn between 4 and 13
As of ROWNUM itself:
with temp as
(select some_column,
rownum rn
from your_table
order by date_value
)
select *
from temp
where rn between 4 and 13

Select most recent status for each ID and department code

I have the following table:
I want to get the most recent status for each dept_code that a CL_ID has. So the desired output would be this:
I have tried the following but this give me just the most recent status for each client and not each of their dept_codes.
SELECT *
FROM [CIMSHR6_MERGED].[dbo].[C3CLSTAT] C
INNER JOIN
(SELECT CLIENT_NUMBER, MAX(STATUS_DATE) AS SDATE
FROM [CIMSHR6_MERGED].[dbo].[C3CLSTAT]
GROUP BY CLIENT_NUMBER) X
ON X.CLIENT_NUMBER = C.CLIENT_NUMBER
AND X.SDATE = C.STATUS_DATE
ORDER BY C.CLIENT_NUMBER
Any help would be much appreciated. Thanks.
A convenient method that works in SQL Server is:
select top (1) cl.*
from [CIMSHR6_MERGED].[dbo].[C3CLSTAT] cl
order by row_number() over (partition by cl_id, dept_code order by status_date desc);
A method that is efficient with the right indexes in almost any database is:
select cl.*
from [CIMSHR6_MERGED].[dbo].[C3CLSTAT] cl
where cl.status_date = (select max(cl2.status_date)
from [CIMSHR6_MERGED].[dbo].[C3CLSTAT] cl2
where cl2.cl_id = cl.cl_id and cl2.dept_code = cl.dept_code
);
The right index is on (cl_id, dept_code, status_date).
I would also use ROW_NUMBER, but with a subquery:
SELECT CL_ID, Status_date, Status, Dept_code
FROM
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY CL_ID, Dept_code ORDER BY Status_date DESC) rn
FROM CIMSHR6_MERGED].[dbo].[C3CLSTAT]
) t
WHERE rn = 1;
1) Firstly group everything on Dept_Code,CL_ID and assign rank for each row with in the group in descending order.
2) Select all the rows with rnk=1 which would display your desired result.
SELECT Z.CL_ID,
Z.Status_Date,
Z.Status,
Z.Dept_Code
FROM
(
SELECT *,
RANK() OVER( PARTITION BY Dept_Code,CL_ID, ORDER BY Status_Date DESC ) AS rnk
FROM [CIMSHR6_MERGED].[dbo].[C3CLSTAT]
) Z
WHERE Z.rnk = 1;
This would work for almost all databases
select * from c3clstat c
where exists
(select 1 from c3clstat c1
where c1.cl_id=c.cl_id
and c1.dept_code=c.dept_code
group by cl_id,dept_code
having c.status_date=max(c1.status_date)
)

Issue with Hive Rank queries

select season,violation_code, cnt,
RANK() over (Partition BY season order by cnt desc) AS rank
from
( select season,violation_code,
count(*) as cnt
from ParkingViolations_seondary
group by season,violation_code
) tmp
where rank <= 3
I'm new to Hive. Can somebody help me what is wrong with the above query?
It throws the following error:
Error while compiling statement:
FAILED: SemanticException [Error 10004]: line 4:6 Invalid table alias
or column reference 'rank': (possible column names are: season,
violation_code, cnt)
Any quick help would be appreciated.
Use subquery to be able to address rank in the where clause:
select season, violation_code, cnt, rnk
from
( select season,violation_code, cnt,
RANK() over (Partition BY season order by cnt desc) AS rnk
from
( select season,violation_code,
count(*) as cnt
from ParkingViolations_seondary
group by season,violation_code
) tmp
)s
where rnk <= 3
Yes i was also able to get it working with the following:
SELECT * FROM
(
SELECT season,violation_code, cnt, RANK() over (Partition BY season ORDER BY cnt DESC) AS frequency
FROM
(SELECT season,violation_code, COUNT(*) as cnt FROM ParkingViolations_seondary
WHERE (violation_code <> 0) and (street_code1 <> 0 or street_code2 <> 0 or street_code3 <> 0)
GROUP BY season,violation_code)TMP
)TMP1
WHERE frequency <= 3;

Get highest value of Oracle table while using Max

I have the follow sql statement. I'm trying to get the highest version. My query is returning multiple results, although sorted by verison desc. How can I just get the highest one?
SELECT pv.version, pv.vin, pv.policyid, pv.segeffdate, pv.segexpdate, pv.changenum from
nsa_al.polvehicle pv
WHERE pv.vin = '2GTEC19T011201788'
AND pv.changenum > 0
AND pv.VERSION = (SELECT MAX(PV.VERSION) FROM NSA_AL.POLVERSION)
ORDER BY pv.version DESC
I've tried to use the rownum = 1 but I kept getting missing ")" error.
Thanks
There are a couple of ways to do this. Here is one with a subquery and ROWNUM:
SELECT *
FROM (
SELECT pv.version, pv.vin, pv.policyid, pv.segeffdate, pv.segexpdate, pv.changenum
FROM nsa_al.polvehicle pv
WHERE pv.vin = '2GTEC19T011201788'
AND pv.changenum > 0
ORDER BY pv.version DESC
) t
WHERE ROWNUM = 1
SQL Fiddle Demo
This will only return a single record. If you need ties, you can use the analytic function RANK() instead.
SELECT *
FROM (
SELECT RANK() OVER (ORDER BY version DESC) rnk, pv.version, pv.vin, pv.changenum
FROM pv
WHERE pv.vin = '2GTEC19T011201788'
AND pv.changenum > 0
ORDER BY pv.version DESC
) t
WHERE rnk = 1
If you prefer to use a MAX aggregate, then it's easiest to do that with a common table expression and JOIN the table back on itself. This could yield multiple results if there are multiple records with the same version:
WITH CTE AS (
SELECT pv.version, pv.vin, pv.changenum
FROM pv
WHERE pv.vin = '2GTEC19T011201788'
AND pv.changenum > 0
)
SELECT *
FROM CTE C
JOIN (
SELECT MAX(version) maxVersion
FROM CTE) C2 ON C.version = C2.maxVersion
More Fiddle