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;
Related
I would like to isolate some emails with specific titles. I can use multiple "like"s connected with an ORs in the where clause. This gives me a number of results. However, if I try to do a ____ in ('____', '____', etc), the code suddenly returns nothing.
This does not work.
select DATE_TRUNC(DATE(send_time,"America/Los_Angeles"), week(monday)) as week,
status,
settings_title,
sum(emails_sent) as emails_sent,
sum(report_summary_opens) as report_summary_opens,
sum(report_summary_unique_opens) as report_summary_unique_opens,
sum(report_summary_subscriber_clicks) as report_summary_subscriber_clicks
from mailchimp.campaigns_view
where status = 'sent'
and settings_title in ('%_LL_%', '%_IC_%', '%_AC_%', '%_CC_%', '%_PC_%')
group by 1,2,3
order by 1 desc
However, this works.
select DATE_TRUNC(DATE(send_time,"America/Los_Angeles"), week(monday)) as week,
status,
settings_title,
sum(emails_sent) as emails_sent,
sum(report_summary_opens) as report_summary_opens,
sum(report_summary_unique_opens) as report_summary_unique_opens,
sum(report_summary_subscriber_clicks) as report_summary_subscriber_clicks
from mailchimp.campaigns_view
where status = 'sent'
and (settings_title like '%_LL_%'
or settings_title like '%_IC_%'
or settings_title like '%_AC_%'
or settings_title like '%_CC_%'
or settings_title like '%_PC_%')
group by 1,2,3
order by 1 desc
I have already tried to include a subquery in my "from" that eliminates all null settings_title. Any ideas why this is not working? Am I missing some small syntax error?
Thanks for the help!
The % symbol will only work with LIKE. For IN it's only equality. Try REGEXP_CONTAINS too.
As in:
SELECT REGEXP_CONTAINS("abcdefg", '(xxx|zzz|yyy|cd)')
Thanks Felipe, very usefull!!!. In my case I used REGEXP_CONTAINS for matching with a multiple patterns added to a table. The select with the column "pattern_str" located in the second position is able to search and find correctly for every portion of the parttern:
WITH CTE_PatternCovid as (
Select STRING_AGG(Pattern,'|') as strPattern from xxxxxxxxx.TEMP.Temp_patternsearch_covid
)
--this convert the multiple patterns into a single line:
--.*MASK.FFP.|.*MASK.KN.|.*TEST.ANTIG.|.*MASK.QUI.|.*SP.*H.DRO.AL.
--then use in this way:
Select ProductName FROM xxxxxxxxx.TEMP.Table_ProductsName_covid
where
regexp_contains (upper(ProductName),(SELECT strPattern FROM CTE_PatternCovid ))
I want to randomly pick 4 rows which are distinct and do not have any entry that matches with any of the 4 chosen columns.
Here is what I coded:
SELECT DISTINCT en,dialect,fr FROM words ORDER BY RANDOM() LIMIT 4
Here is some data:
**en** **dialect** **fr**
number SFA numero
number TRI numero
hotel CAI hotel
hotel SFA hotel
I want:
**en** **dialect** **fr**
number SFA numero
hotel CAI hotel
Some retrieved rows would have something similar with each other, like having the same en or the same fr, I would like to retrieved rows that do not share anything similar with each other, how do I do that?
I think I’d do this in the front end code rather the dB, here’s a pseudo code (don’t know what your node looks like):
var seenEn = “en not in (''“;
var seenFr = “fr not in (''“;
var rows =[];
while(rows.length < 4)
{
var newrow = sqlquery(“SELECT *
FROM table WHERE “ + seenEn + “) and ”
+ seenFr + “) ORDER BY random() LIMIT 1”);
if(!newrow)
break;
rows.push(newrow);
seenEn += “,‘“+ newrow.en + “‘“;
seenFr += “,‘“+ newrow.fr + “‘“;
}
The loop runs as many times as needed to retrieve 4 rows (or maybe make it a for loop that runs 4 times) unless the query returns null. Each time the query returns the values are added to a list of values we don’t want the query to return again. That list had to start out with some values (null) that are never in the data, to prevent a syntax error when concatenation a comma-value string onto the seenXX variable. Those syntax errors can be avoided in other ways like having a Boolean of “if it’s the first value don’t put the comma” but I chose to put dummy ineffective values into the sql to make the JS simpler. Same goes for the
As noted, it looks like JS to ease your understanding but this should be treated as pseudo code outlining a general algorithm - it’s never been compiled/run/tested and may have syntax errors or not at all work as JS if pasted into your file; take the idea and work it into your solution
Please note this was posted from an iphone and it may have done something stupid with all the apostrophes and quotes (turned them into the curly kind preferred by writers rather than the straight kind used by programmers)
You can use Rank or find first row for each group to achieve your result,
Check below , I hope this code will help you
SELECT 'number' AS Col1, 'SFA' AS Col2, 'numero' AS Col3 INTO #tbl
UNION ALL
SELECT 'number','TRI','numero'
UNION ALL
SELECT 'hotel','CAI' ,'hotel'
UNION ALL
SELECT 'hotel','SFA','hotel'
UNION ALL
SELECT 'Location','LocationA' ,'Location data'
UNION ALL
SELECT 'Location','LocationB','Location data'
;
WITH summary AS (
SELECT Col1,Col2,Col3,
ROW_NUMBER() OVER(PARTITION BY p.Col1 ORDER BY p.Col2 DESC) AS rk
FROM #tbl p)
SELECT s.Col1,s.Col2,s.Col3
FROM summary s
WHERE s.rk = 1
DROP TABLE #tbl
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>.
SELECT DISTINCT Invoice.InvNo, Invoice.OrderNo, Part.PartNo,
orders.orddate AS Order_Date, Invoice.InvDate AS Bill_Date,
MiscChg.Descr, MiscChg.RegFee, Invoice.InvAmt,
Orders.ClaimNo, Firm.FirmName AS Ordering_Firm,
**oppatty.attyid(WHERE oppatty.attyfor = 13)**, Location.Name1 AS Location
The bolded section is the part I'm having trouble with. I know what I have isn't right, but it demonstrates what I would like to accomplish. In the oppatty table, there could be several items listed. I want it to only display "AttyID for the entry that has an ATTYFOR = 13".
Hope this make sense, thanks
Jack
You need to add a CASE WHEN to the select statement.
SELECT DISTINCT
Invoice.InvNo,
Invoice.OrderNo,
Part.PartNo,
orders.orddate AS Order_Date,
Invoice.InvDate AS Bill_Date,
MiscChg.Descr,
MiscChg.RegFee,
Invoice.InvAmt,
Orders.ClaimNo,
Firm.FirmName AS Ordering_Firm,
CASE WHEN oppatty.AttyFor = 13
THEN oppatty.AttyId
ELSE '' END AS attyfor,
Location.Name1 AS Location
FROM
.........
This will display the AttyId field when the row's AttyFor field is equal to 13 and show an empty string when it's not.
Your query has no from or where clause and your question is a bit jumbled, but even so, I think I understand what you want to do. Assuming it's acceptable to fill the "AttyID" values with null where "AttyFor" isn't equal to 13, then you could just use a case statement. Try something like this
select
stuff.things,
case
where oppatty.attyfor <> 13 then null
else oppatty.attyid
end as attyid,
stuff.others
from
oppatty
join stuff on oppatty.ID = stuff.ID
If that's not your desired result, and you'd rather entirely exclude rows where "AttyFor" isnt equal to 13, then just use a where clause.
select
stuff.things,
oppatty.attyid,
stuff.others
from
oppatty
join stuff on oppatty.ID = stuff.ID
where
oppatty.attyfor = 13
I have two SQL queries that I would like to combined into one, if its possible. The fist is to get information about a shop order and the second is to get revision information from all previous records with the same shop_order_id.
The first query:
SELECT so.shop_order_id, so.shop_order_suffix, so.status, so.mfg_method, so.description
FROM shop_order so
WHERE so.shop_order_id = 'ZZ1810C'
AND so.shop_order_suffix = '000';`
The second query:
SELECT so.user_att27, so.user_att28
FROM shop_order so
WHERE so.shop_order_id LIKE 'ZZ1810C%'
ORDER BY shop_order_suffix DESC;`
Is it possible to combined them so that they run at one time and if so how would i got about doing it?
I think you need a JOIN :
SELECT so.shop_order_id, so.shop_order_suffix, so.status, so.mfg_method, so.description, so2.user_att27, so2.user_att28
FROM shop_order so
JOIN shop_order so2 ON so2.shop_order_id LIKE 'ZZ1810C%'
WHERE so.shop_order_id = 'ZZ1810C' AND so.shop_order_suffix = '000'
ORDER BY shop_order_suffix DESC;
What do you want the results to be? An example would be helpful.
The following combines the two conditions:
SELECT so.shop_order_id, so.shop_order_suffix, so.status, so.mfg_method,
so.description, so.user_att27, so.user_att28
FROM shop_order so
WHERE so.shop_order_id LIKE 'ZZ1810C%'
ORDER BY shop_order_suffix DESC;
This will list all the rows for the shop order, with the initial information duplicated on each row. The additional fields tell you about the revisions.
You mentioned that the intent of the second query is to get all previous records with the SAME shop_order_id, but the second query filters on shop_order_ids that START WITH the provided text, as specified by the LIKE clause.
If the intent is to include all of these, the two queries are from the same table, so just grab the union of all columns for all such entries. I'd order by shop_order_id so that the one without any additional suffix text shows up first:
SELECT so.shop_order_id, so.shop_order_suffix, so.status, so.mfg_method, so.description, so.user_att27, so.user_attr28 FROM shop_order so WHERE so.shop_order_id LIKE 'ZZ1810C%' AND so.shop_order_suffix='000' ORDER BY so.shop_order_id DESC;