I am looking to run my query (below) by displaying latest value for "DATA_POINT_UPLOAD_DATA"."VALUE" , except 'READY'. Currently, it displays all 'READY' values, however, I want to do the opposite by displaying any values up to the time of execution except 'READY'.
Here is my current query:
select "DATA_POINT_UPLOAD_DATA"."LAST_UPDATED_TIMESTAMP" as "TIMESTAMP",
"DATA_POINT_UPLOAD_DATA"."VALUE" as "COMMENTS"
from "DB"."COMPONENT" "COMPONENT",
"DB"."COMPONENT_DATA_POINT" "COMPONENT_DATA_POINT",
"DB"."DATA_POINT_UPLOAD_DATA" "DATA_POINT_UPLOAD_DATA"
where "COMPONENT_DATA_POINT"."ID"="DATA_POINT_UPLOAD_DATA"."COMPONENT_DATA_POINT_ID"
and "COMPONENT"."ID"="COMPONENT_DATA_POINT"."COMPONENT_ID"
and "DATA_POINT_UPLOAD_DATA"."VALUE" ='READY'
and "DATA_POINT_UPLOAD_DATA"."LAST_UPDATED_TIMESTAMP" between ('01-JUN-17') and ('30-JUN-17')
and "COMPONENT_DATA_POINT"."NAME" ='StateOfItem'
and "COMPONENT"."SITE_ID" in('abc123');
Any help would be greatly appreciated.
In your WHERE clause you have this: "DATA_POINT_UPLOAD_DATA"."VALUE" ='READY'. That means you want to display the rows where DATA_POINT_UPLOAD_DATA has the value 'READY'.
Change your query and instead of using = try using != or <>.
SELECT "DATA_POINT_UPLOAD_DATA"."LAST_UPDATED_TIMESTAMP" AS "TIMESTAMP",
"DATA_POINT_UPLOAD_DATA"."VALUE" AS "COMMENTS"
FROM "DB"."COMPONENT" "COMPONENT",
"DB"."COMPONENT_DATA_POINT" "COMPONENT_DATA_POINT",
"DB"."DATA_POINT_UPLOAD_DATA" "DATA_POINT_UPLOAD_DATA"
WHERE "COMPONENT_DATA_POINT"."ID" ="DATA_POINT_UPLOAD_DATA"."COMPONENT_DATA_POINT_ID"
AND "COMPONENT"."ID" ="COMPONENT_DATA_POINT"."COMPONENT_ID"
AND "DATA_POINT_UPLOAD_DATA"."VALUE" !='READY'
AND "DATA_POINT_UPLOAD_DATA"."LAST_UPDATED_TIMESTAMP" BETWEEN ('01-JUN-17') AND ('30-JUN-17')
AND "COMPONENT_DATA_POINT"."NAME" ='StateOfItem'
AND "COMPONENT"."SITE_ID" IN('abc123');
You are asking for the latest record per VALUE now. You are only selecting VALUE and LAST_UPDATED_TIMESTAMP, however. So what you are asking is merely the maximum LAST_UPDATED_TIMESTAMP per VALUE. In SQL this translates to MAX(last_updated_timestamp) with GROUP BY value.
Select
max(last_updated_timestamp) as "timestamp",
value as comments
From db.data_point_upload_data
Where value <> 'READY'
and last_updated_timestamp between '2017-06-01' and '2017-06-30'
and cdp_id in
(
select id
from db.component_data_point
where name = 'StateOfItem'
and component_id in (select id from db.component where site_id = 'abc123')
)
Group by value;
Sorry to say, but that is a horrible query. Almost only upper case so as to minimize readability, table alias names that are no alias names, a join syntax that was made redundant twentyfive years ago, date string literals that only work in certain language settings, and unnecessary joins.
Then you select records with value = 'READY' and say that you want records that are not 'READY'. Well, then: WHERE NOT value = 'READY' or simply WHERE value <> 'READY'.
Here is the altered query:
Select
last_updated_timestamp as "timestamp",
value as comments
From db.data_point_upload_data
Where value <> 'READY'
and last_updated_timestamp between '2017-06-01' and '2017-06-30'
and cdp_id in
(
select id
from db.component_data_point
where name = 'StateOfItem'
and component_id in (select id from db.component where site_id = 'abc123')
);
If you only want to see the latest n rows, then order by last_updated_timestamp desc limit <n>.
Related
I suck at explaining this issue, but I hope someone understands.
How do I filter something out of a column if it meets just one criteria out of the whole value?
So in this example I want to filter out any value that includes "First Touch", even if the value has other SpecialNeedsTagNames as well. For example "First Touch, Do Not Contact, Self-Serve Pilot" etc..
SELECT count(*) AS count
FROM
(select *
from OperationalReporting.VW_Delivery
WHERE DeliveryCountry in ('NO',
'FI',
'DK',
'SE',
'IS')) AS expr_qry
WHERE "CountryOfUse" = 'Sweden'
AND "OrderStatus" IN ('Booked',
'Order Placed')
AND "IsDelivered" = 'false'
AND "Model" NOT IN ('Model QW',
'Model PX',
'Model ZY')
AND ((SalesAdvisorHomeStore like 'EU-SE%'
OR CommisionabaleStore like 'EU-SE%')
AND (SpecialNeedsTagName is null
or (SpecialNeedsTagName not like '%First Touch%')))
ORDER BY count DESC
LIMIT 50000;
Currently it only filters out the values that ONLY have "First Touch", as soon as it has a combined value it still outputs in the column.Faulty values
So first things first, you may want to unify all values in you column by giving UPPER or LOWER. The where statement would look like this:
WHERE UPPER(SpecialNeedsTagName) LIKE 'FIRST TOUCH%'
If you want to make sure that there are no nulls add AND IS NOT NULL.
This where will return you all of results that starts with FIRST TOUCH. If you are expecting that this phrase may occure in the middle of string add % at the beginning ('%FIRST TOUCH%')
Try This :
SELECT count(*) AS count
FROM
(select *
from XX.XX_XX
WHERE NOT EXISTS (select * from XX.XX_XX where UPPER(SpecialNeedsTagName)
LIKE '%First Touch%'))
ORDER BY count DESC
LIMIT 50000;
So I have no experience in SQL but I have no resource to use for identifying duplicates.
The problem: A SER_NO(serial #) can show up on 2 different dates (EVENT_TS), and I only want to see the first occurrence the SER_NO shows up.
If I have the choice, I would keep the date that the SER_NO showed up on, and not any other date after, but at this point, I just don't want to see duplicate SER_NO
I went the SELECT DISTINCT route and that doesn't help... I need to identify if the SER_NO occurs more than once, and then if it does, I aim to keep the first occurrence (MIN DATE).
SELECT
EVENT_TS, EVENT_NO, FAC_PROD_FAM_CD, SER_NO, DISC_AREA_ID, DISC_AREA_DESC,
QUALITY_VELOCITY, CMPNT_SERIAL_NO, PROTOTYPE_IND, EXT_CPY_STAT
FROM ABUS_DW.V_BIQ_R8_QWB_EVENTS
WHERE
(FAC_PROD_FAM_CD='ACOM' OR FAC_PROD_FAM_CD='SCOM' OR FAC_PROD_FAM_CD='LAP' OR
FAC_PROD_FAM_CD='RM' OR FAC_PROD_FAM_CD='SCRD')
AND (DISC_AREA_ID='400' OR DISC_AREA_ID='450')
AND PROTOTYPE_IND<>'Y' AND EXT_CPY_STAT<>'D'
AND EVENT_TS>=<Parameters.Start Date> ORDER BY EVENT_TS
Also, I am doing this in Tableau's Custom SQL Query feature... which.. without knowing anything about SQL or the basic syntax... seems to not like any fancy tricks. Maybe it does... I don't know... But all I've gotten are errors using other people's scripts. It seems very specific on the syntax it wants to see.
Assuming that every other field you're selecting on (besides the date) is also duplicated, you can use some aggregation in your query to squish the output records together, using either the min(event_ts) or max(event_ts) depending on what you want to see:
SELECT MIN(EVENT_TS) as EVENT_TS
,EVENT_NO
,FAC_PROD_FAM_CD
,SER_NO
,DISC_AREA_ID
,DISC_AREA_DESC
,QUALITY_VELOCITY
,CMPNT_SERIAL_NO
,PROTOTYPE_IND
,EXT_CPY_STAT
FROM ABUS_DW.V_BIQ_R8_QWB_EVENTS
WHERE FAC_PROD_FAM_CD IN ('ACOM', 'SCOM', 'LAP', 'RM', 'SCRD')
AND DISC_AREA_ID IN ('400','450')
AND PROTOTYPE_IND <> 'Y'
AND EXT_CPY_STAT <> 'D'
AND EVENT_TS >= <Parameters.Start DATE>
GROUP BY
EVENT_NO
,FAC_PROD_FAM_CD
,SER_NO
,DISC_AREA_ID
,DISC_AREA_DESC
,QUALITY_VELOCITY
,CMPNT_SERIAL_NO
,PROTOTYPE_IND
,EXT_CPY_STAT
ORDER BY EVENT_TS
If each row of your duplicate records has distinct values for FAC_PROD_FAM_CD, SER_NO, DISC_AREA_ID, etc... then you'll have to get fancier. You could use a correlated subquery as one option:
SELECT EVENT_TS
,EVENT_NO
,FAC_PROD_FAM_CD
,SER_NO
,DISC_AREA_ID
,DISC_AREA_DESC
,QUALITY_VELOCITY
,CMPNT_SERIAL_NO
,PROTOTYPE_IND
,EXT_CPY_STAT
FROM ABUS_DW.V_BIQ_R8_QWB_EVENTS AS t1
WHERE FAC_PROD_FAM_CD IN ('ACOM', 'SCOM', 'LAP', 'RM', 'SCRD')
AND DISC_AREA_ID IN ('400','450')
AND PROTOTYPE_IND <> 'Y'
AND EXT_CPY_STAT <> 'D'
AND EVENT_TS =
(
SELECT MIN(EVENT_TS)
FROM ABUS_DW.V_BIQ_R8_QWB_EVENTS
WHERE FAC_PROD_FAM_CD IN ('ACOM', 'SCOM', 'LAP', 'RM', 'SCRD')
AND DISC_AREA_ID IN ('400','450')
AND PROTOTYPE_IND <> 'Y'
AND EXT_CPY_STAT <> 'D'
AND EVENT_TS >= <Parameters.Start DATE>
AND t1.EVENT_ID = EVENT_ID
)
ORDER BY EVENT_TS;
Here, in a subquery, we get the min(event_ts) for the event_id given all the same WHERE conditions and then we restrict the main query by that min(event_id).
I got a problem regarding grouping if a value is the same as in the row above.
Our statement looks like this:
SELECT pat_id,
treatData.treatmentdate AS Date,
treatMeth.name AS TreatDataTableInfo,
treatData.treatmentid AS TreatID
FROM dialysistreatmentdata treatData
LEFT JOIN hdtreatmentmethods treatMeth
ON treatMeth.id = treatData.hdtreatmentmethodid
WHERE treatData.hdtreatmentmethodid IS NOT NULL
AND Year(treatData.treatmentdate) >= 2013
AND ekeyid = 12
ORDER BY treatData.ekeyid,
treatmentdate DESC,
treatdatatableinfo;
The output looks like this:
The desired output should be grouped if the value is the same as in the row/rows before and ther should be a ToDate as you can see in the screenshot which is the date of the next row -1 day.
The desired output should look like this:
I hope someone has a solution regarding this matter!
Or maybe someone has an idea how to solve this problem within qlikview.
Looking forward for solutions
Michael
You want to collapse episodes of treatment into single rows. This is a "gaps-and-islands" problem. I like the difference of row numbers approach:
select patid, min(date) as fromdate, max(date) as todate, TreatDataTableInfo,
min(treatid)
from (select td.Pat_ID, td.TreatmentDate As Date, tm.Name As TreatDataTableInfo,
td.TreatmentID As TreatID,
row_number() over (partition by td.pat_id order by td.treatmentdate) as seqnum_p,
row_number() over (partition by td.pat_id, tm.name order by td.treatment_date) as seqnum_pn
from DialysisTreatmentData td Left join
HDTreatmentMethods tm
On tm.ID = td.HDTreatmentMethodID
where td.HDTreatmentMethodID Is Not Null And
td.TreatmentDate) >= '2013-01-01' and
EKeyID = 12
) t
group by patid, TreatDataTableInfo, (seqnum_p - seqnum_pn)
order by patid, TreatmentDate Desc, TreatDataTableInfo;
Note: This uses the ANSI standard window function row_number(), which is available in most databases.
Below is a possible Qlikview solution. I've put some comments in the script. If it's not clear just let me know. The result picture is below the script.
RawData:
Load * Inline [
Pat_ID,Date,TreatDataTableInfo,TreatId
PatNum_12,08.07.2016,HDF Pradilution,1
PatNum_12,07.07.2016,HDF Predilution,2
PatNum_12,23.03.2016,HD,3
PatNum_12,24.11.2015,HD,4
PatNum_12,22.11.2015,HD,5
PatNum_12,04.09.2015,HD,6
PatNum_12,01.09.2015,HD,7
PatNum_12,30.07.2015,HD,8
PatNum_12,12.01.2015,HD,9
PatNum_12,09.01.2015,HD,10
PatNum_12,26.08.2014,Hemodialysis,11
PatNum_12,08.07.2014,Hemodialysis,12
PatNum_12,23.05.2014,Hemodialysis,13
PatNum_12,19.03.2014,Hemodialysis,14
PatNum_12,29.01.2014,Hemodialysis,15
PatNum_12,14.12.2013,Hemodialysis,16
PatNum_12,26.10.2013,Hemodialysis,17
PatNum_12,05.10.2013,Hemodialysis,18
PatNum_12,03.10.2013,HD,19
PatNum_12,24.06.2013,Hemodialysis,20
PatNum_12,03.06.2013,Hemodialysis,21
PatNum_12,14.05.2013,Hemodialysis,22
PatNum_12,26.02.2013,HDF Postdilution,23
PatNum_12,23.02.2013,HDF Pradilution,24
PatNum_12,21.02.2013,HDF Postdilution,25
PatNum_12,07.02.2013,HD,26
PatNum_12,25.01.2013,HDF Pradilution,27
PatNum_12,18.01.2013,HDF Pradilution,28
];
GroupedData:
Load
*,
// assign new GroupId for all rows where the TreatDataTableInfo is equal
if( RowNo() = 1, 1,
if( TreatDataTableInfo <> peek('TreatDataTableInfo'),
peek('GroupId') + 1, peek('GroupId'))) as GroupId,
// assign new GroupSubId (incremental int) for all the records in each group
if( TreatDataTableInfo <> peek('TreatDataTableInfo'),
1, peek('GroupSubId') + 1) as GroupSubId,
// pick the first Date field value and spread it acccross the group
if( TreatDataTableInfo <> peek('TreatDataTableInfo'), TreatId, peek('TreatId_Temp')) as TreatId_Temp
Resident
RawData
;
Drop Table RawData;
right join (GroupedData)
// get the max GroupSubId for each group and right join it to
// the GroupedData table to remove the records we dont need
MaxByGroup:
Load
max(GroupSubId) as GroupSubId,
GroupId
Resident
GroupedData
Group By
GroupId
;
// these are not needed anymore
Drop Fields GroupId, GroupSubId, TreatId;
// replace the old TreatId with the new TreatId_Temp field
// which contains the first TreatId for each group
Rename Field TreatId_Temp to TreatId;
I want to do a select in a table named ALBARANES that it's going to show me all
the columns of the table. This select has inputs values to do the where clauses.
Inputs: #serie, #client
What I want is: If #serie's value is null then show me all the columns regardles of the column value of ALBARANES.SERIE, but if #serie has a value not null then do a clause using it.
SELECT * FROM ALBARANES AC
WHERE
AC.SERIE = #serie/*Code when #serie has value not null*/
AC.FECHA < (SELECT CAST ('Now' as date) from RDB$DATABASE)
And the same with the input #client. How can I implement this select?
You want:
WHERE (AC.SERIE = #serie or #serie is null) and
ac.fecha < date(now())
Your question is tagged MySQL. However, your date logic is not MySQL, so I changed it. If your question is mistagged, then you may want your original logic.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to get the record of a table who contains the maximum value?
I've got an aggregate query like the following:
SELECT TrainingID, Max(CompletedDate) as CompletedDate, Max(Notes) as Notes --This will only return the longest notes entry
FROM HR_EmployeeTrainings ET
WHERE (ET.AvantiRecID IS NULL OR ET.AvantiRecID = #avantiRecID)
GROUP BY AvantiRecID, TrainingID
Which is working, and returns correct data most of the time, but I noticed a problem. The Notes field which gets returned will not necessarily match the record that the max(completedDate) is from. Instead it will be the one with the longest string? Or the one with the highest ASCII value? What does SQL Server do in the event of a tie between two records? I'm not even sure. What I want to get is the notes field from the max(completedDate) record. How should I got about doing this?
You can use a subquery. The subquery will get the Max(CompletedDate). You then take this value and join on your table again to retrieve the note associate with that date:
select ET1.TrainingID,
ET1.CompletedDate,
ET1.Notes
from HR_EmployeeTrainings ET1
inner join
(
select Max(CompletedDate) CompletedDate, TrainingID
from HR_EmployeeTrainings
--where AvantiRecID IS NULL OR AvantiRecID = #avantiRecID
group by TrainingID
) ET2
on ET1.TrainingID = ET2.TrainingID
and ET1.CompletedDate = ET2.CompletedDate
where ET1.AvantiRecID IS NULL OR ET1.AvantiRecID = #avantiRecID
Ah yes, that is how it is intended in SQL. You get the Max of every column seperately. It seems like you want to return values from the row with the max date, so you have to select the row with the max date. I prefer to do this with a subselect, as the queries keep compact easy to read.
SELECT TrainingID, CompletedDate, Notes
FROM HR_EmployeeTrainings ET
WHERE (ET.AvantiRecID IS NULL OR ET.AvantiRecID = #avantiRecID)
AND CompletedDate in
(Select Max(CompletedDate) from HR_EmployeeTrainings B
where B.TrainingID = ET.TrainingID)
If you also want to match by AntiRecID you should include that in the subselect as well.
Each MAX function is evaluated individually. So MAX(CompletedDate) will return the value of the latest CompletedDate column and MAX(Notes) will return the maximum (i.e. alphabeticaly highest) value.
You need to structure your query differently to get what you want. This question had actually already been asked and answered several times, so I won't repeat it:
How to find the record in a table that contains the maximum value?
Finding the record with maximum value in SQL
There's no easy way to do this, but something like this will work:
SELECT ET.TrainingID,
ET.CompletedDate,
ET.Notes
FROM
HR_EmployeeTrainings ET
inner join
(
select TrainingID, Max(CompletedDate) as CompletedDate
FROM HR_EmployeeTrainings
WHERE (ET.AvantiRecID IS NULL OR ET.AvantiRecID = #avantiRecID)
GROUP BY AvantiRecID, TrainingID
) ET2
on ET.TrainingID = ET2.TrainingID
and ET.CompletedDate = ET2.CompletedDate