NOT statement in where Clause in SQL Server Slow - sql

I have this query , where the results are as expected but the query is really slow. The below is just an example
SELECT ispending, isviewable, iscomparable, ID
FROM tableA
WHERE
name = 'Karen'
AND NOT ((ispending = 'F' AND isviewable = '0') OR
(ispending = 'T' AND iscomparable = '0') OR
(ispending = 'T' AND iscomparable IS NULL AND isviewable = '0') OR
(ispending IS NULL AND iscomparable = '0'))
How to achieve the same result but not using the 'NOT' statement in the where clause?
I tried changing the not to be within the clause
WHERE (ispending != 'F' AND isviewable != '0') OR
(ispending != 'T' AND iscomparable != '0') OR
(ispending != 'T' AND iscomparable IS NOT NULL AND isviewable != '0') OR
(ispending IS NOT NULL AND iscomparable !='0')
but the expected results are different.

You're second code block is quite close. De Morgan's law guides in trying to switch operands on boolean operations.
The code is correct to switch = with != (the negation of the =). But you will also need to negate conjunctions/disjunctions. In essence: AND becomes OR and vice versa.
WHERE (ispending != 'F' OR isviewable != '0') AND
(ispending != 'T' OR iscomparable != '0') AND
(ispending != 'T' OR iscomparable IS NOT NULL OR isviewable != '0') AND
(ispending IS NOT NULL OR iscomparable != '0')
Now we have the logical equivalent.

Related

How to check Not null value from Array in SQL

I'm facing the problem while checking null value from array, I tried by adding the AND condition in where clause "AND "txt" IS not null" but it's not working.
Below is my query please help me out from this.
SELECT %s
"module-id" AS module_id,
"per-num" AS per_num,
RTRIM ("txt"[1] || "txt"[2] || "txt"[3] || "txt"[4] || "txt"[5] ||
"txt"[6] || "txt"[7] || "txt"[8] || "txt"[9] || "txt"[10])
AS note_text,
"page-no" AS page_number,
"upd-dat" AS updated_on,
"upd-tim" AS updated_time,
"upd-usr-id" AS updated_by,
CASE WHEN "module-id" = 1 THEN 'Common'
WHEN "module-id" = 5 THEN 'Rents'
WHEN "module-id" = 8 THEN 'Arrears'
END AS category
FROM pub."perpad"
WHERE "module-id" IN (1, 5, 8)
AND ("per-num" > :perNumFrom
OR ("per-num" = :perNumFrom AND "module-id" > :moduleIdFrom)
OR ("per-num" = :perNumFrom AND "module-id" = :moduleIdFrom AND "page-no" >= :pageNumFrom))
AND "upd-dat" >= :fromDate %s
AND "txt" IS not null
Thanks.

Multi-if else using question mark

I need to evaluate the CD_MARCHE according to CD_AXE_MCH 's values in pig. I should only use the question mark option as bellow:
(CD_AXE_MCH IN ('PLIB','ATPE','COMM') ? 'P': (CD_AXE_MCH == 'PME') ?
'E': (CD_AXE_MCH == 'AGRI') ? 'A': (CD_AXE_MCH == 'OBNL') ?
'O':(CD_AXE_MCH == 'COLL') ? 'C' :(CD_AXE_MCH == 'EFIN') ?
'B' :'X') AS CD_MARCHE,
But this return this error
mismatched input '?' expecting RIGHT_PAREN
How can I resolve it please ?
In this scenario it's easier to use a CASE statement. Available from Pig version 0.11+.
CASE
WHEN CD_AXE_MCH MATCHES 'PLIB|ATPE|COMM' THEN 'P'
WHEN CD_AXE_MCH == 'PME' THEN 'E'
WHEN CD_AXE_MCH == 'AGRI' THEN 'A'
WHEN CD_AXE_MCH == 'OBNL' THEN 'O'
WHEN CD_AXE_MCH == 'COLL' THEN 'C'
WHEN CD_AXE_MCH == 'EFIN' THEN 'B'
ELSE 'B'
END CD_MARCHE
If that's not feasible/supported, make sure to place the parentheses correctly.
(CD_AXE_MCH MATCHES 'PLIB|ATPE|COMM' ? 'P' : (CD_AXE_MCH == 'PME' ? 'E' : (CD_AXE_MCH == 'AGRI' ? 'A' : (etc.))))

Count results generated by case statement

I'm working on a query that analyzes two records and checks whether one record matches the second record. If record 1 column matches record 2 column then there's no error. If record 1 column does not match record 2 column then there's an error. I want to be able to count the errors per YPID. For the life of me... I can't figure it out. Help!
Here's my query:
select r1.ypid, r1.business_name as Base_Listed_Name, r1.street_address as Base_Listed_Address, r1.city as Base_Listed_City, r1.state as Base_Listed_State, r1.zip5 as Base_Listed_Zip, rmve1.value as Base_URL,
r2.business_name as Google_Scanned_Listed_Name, r2.street_address as Google_Scanned_Listed_Address, r2.city as Google_Scanned_Listed_City, r2.state as Google_Scanned_Listed_City, r2.zip5 as Google_Scanned_Listed_Zip, rmve2.value as Google_Scanned_URL,
ls.presence_score, ls.listing_score,
case
when r1.business_name = r2.business_name then 'no_error'
else 'error'
end Business_Name_Status,
case
when r1.latitude = r2.latitude then 'no_error'
when r1.longitude = r2.longitude then 'no_error'
when r1.latitude is null or r1.latitude in ('0') then (case when r1.street_address = r2.street_address then 'no_error' else 'error' end)
else 'error'
end Street_Address_Status,
case
when r1.city = r2.city then 'no_error'
else 'error'
end City_Status,
case
when r1.state = r2.state then 'no_error'
else 'error'
end State_Status,
case
when r1.zip5 = r2.zip5 then 'no_error'
else 'error'
end Zip_Status,
case
when lower(replace(replace(replace(replace(replace(replace(rmve1.value, 'http://www.', null), 'www.', null), 'https://www.', null), 'http://', null), 'https://', null), 'wwww.', null))
= lower(replace(replace(replace(replace(replace(replace(rmve2.value, 'http://www.', null), 'www.', null), 'https://www.', null), 'http://', null), 'https://', null), 'wwww.', null)) then 'no_error'
else 'error'
end URL_Status
from mdm2.records r1 join mdm2.records r2 on r1.ypid = r2.ypid join mdm2.presence_listing_statuses ls on r1.ypid = ls.ypid
left outer join mdm2.record_mult_val_exts rmve1 on r1.id = rmve1.record_id and rmve1.extension_type = 'urls' and rmve1.value_type = 'primary'
left outer join mdm2.record_mult_val_exts rmve2 on r2.id = rmve2.record_id and rmve2.extension_type = 'urls' and rmve2.value_type = 'primary'
where r1.ypid in ('5625222','13846403','21974776','22806234','30303664','453728041')
and r1.source_code = 'PPA'
and r2.source_code = 'GOOG';
results
|YPID|BASE_LISTED_NAME|BASE_LISTED_ADDRESS|BASE_LISTED_CITY|BASE_LISTED_STATE|BASE_LISTED_ZIP|BASE_URL|GOOGLE_SCANNED_LISTED_NAME|GOOGLE_SCANNED_LISTED_ADDRESS|GOOGLE_SCANNED_LISTED_CITY|GOOGLE_SCANNED_LISTED_CITY_1|GOOGLE_SCANNED_LISTED_ZIP|GOOGLE_SCANNED_URL|PRESENCE_SCORE|LISTING_SCORE|BUSINESS_NAME_STATUS|STREET_ADDRESS_STATUS|CITY_STATUS|STATE_STATUS|ZIP_STATUS|URL_STATUS|
|5625222|Affinity Insurance Agency|5702 S Staples St Suite G|Corpus Christi|TX|78413|http://affinityia.com|Affinity Insurance Agency|5702 S Staples St Suite G|Corpus Christi|TX|78413|http://corpuschristiinsuranceprovider.com|90|97|no_error|no_error|no_error|no_error|no_error|error|
|13846403|Party Bazaar|4435 Lovers Ln|Dallas|TX|75225|www.partybazaardallas.com|Party Bazaar|4435 Lovers Ln|Dallas|TX|75225|http://partybazaardallas.com|93|100|no_error|no_error|no_error|no_error|no_error|no_error|
|21974776|Alterations To Go|2100 Arden Way Ste 150|Sacramento|CA|95825|http://www.alterationstogosacramento.com|Alterations To Go|2100 Arden Way # 150|Sacramento|CA|95825|http://alterations-togo.com|91|99|no_error|no_error|no_error|no_error|no_error|error|
|22806234|RV America|3640 Chambers Rd|Aurora|CO|80011|http://www.rvamericainc.com/pages/rv%20financing|RV America|3640 Chambers Rd|Aurora|CO|80011|http://rvamericainc.com|83|91|no_error|no_error|no_error|no_error|no_error|error|
|30303664|Sorelli Hair Studio & Spa|400 Saint Andrews Blvd|Melbourne|FL|32940|http://sorellihairstudio.com|Sorelli Hair Studio & Spa|400 Saint Andrews Blvd|Melbourne|FL|32940|http://sorellihairstudio.com|91|99|no_error|no_error|no_error|no_error|no_error|no_error|
|453728041|Carolina Driving School|534 Walkertown Guthrie Rd|Winston Salem|NC|27101|http://www.carolinadriving.com|Carolina Driving School|534 Walkertown Guthrie Rd|Winston Salem|NC|27101|http://carolinadrivingschool.com|87|97|no_error|no_error|no_error|no_error|no_error|error|
i guess you need to use LEAD , LAG function .
check this link http://oracle-base.com/articles/misc/lag-lead-analytic-functions.php
LAG function is used to access data from a previous row
LEAD function is used to return data from the next row.
by this you can compare 1st row with 2nd row

Using Multiple ANDs and ORs in ANSI SQL

I have a simple SQL query:
SELECT
w.fizz
FROM
widgets w
WHERE
w.special_id = 2394
AND w.buzz IS NOT NULL
AND w.foo = 12
In pseudo-code, this WHERE clause could be thought of as:
if(specialId == 2394 && buzz != null && foo == 12)
I now want to change this query so that it returns all widgets whose special_id is 2394, and whose buzz is not null, and whose foo is 12, OR whose special_id is 2394, and whose blah is 'YES', and whose num is 4. In pseudo-code:
if(specialId == 2394 && (buzz != null && foo == 12) || (blah == "YES" && num == 4))
I tried the following, only to get errors:
SELECT
w.fizz
FROM
widgets w
WHERE
w.special_id = 2394
AND
(
w.buzz IS NOT NULL
AND w.foo = 12
)
OR
(
w.blah = 'YES'
AND w.num = 4
)
Any ideas? Thanks in advance!
SELECT
w.fizz
FROM
widgets w
WHERE
w.special_id = 2394
AND
(
(
w.buzz != null
AND w.foo = 12
)
OR
(
w.blah = 'YES'
AND w.num = 4
)
)
Add additional brackets surrounding "OR", because "OR" has less priority than "AND".

Progress DB, need to merge two queries

I have 2 progress database queries and I'm trying to merge them into one statement, but I am getting errors. Each of these queries simply returns a number and I would like to sum those 2 numbers together. Either that or make another query from scratch. They both take in a set of value codes for "DM1" and they both accept 1 "product".
Query 1
SELECT SUM(opn3.samt)
FROM PUB.ord ord3, PUB.opn opn3
WHERE
ord3.subsnum = opn3.subsnum
AND ord3.onum = opn3.onum
AND ord3.DM1 != ''
AND ord3.DM1 IN('XCWAJC25','WCWAMO73')
AND ord3.prdcde = 'CSC'
AND ord3.stat != 16
AND opn3.samt >= 0
GROUP BY ord3.DM1, ord3.prdcde
Query 2
SELECT SUM((-1 * opn2.samt) + ord2.samt)
FROM PUB.ord ord2, PUB.opn opn2
WHERE
ord2.subsnum = opn2.subsnum
AND ord2.onum = opn2.onum
AND ord2.DM1 != ''
AND ord2.DM1 IN('XCWAJC25','WCWAMO73')
AND ord2.prdcde = 'CSC'
AND ord2.stat = 16
AND opn2.samt < 0
GROUP BY ord2.DM1, ord2.prdcde
Merge attempt so far...
SELECT SUM(opn3.samt + (SELECT SUM((-1 * opn2.samt) + ord2.samt)
FROM PUB.ord ord2, PUB.opn opn2
WHERE
ord2.subsnum = opn2.subsnum
AND ord2.onum = opn2.onum
AND ord2.DM1 != ''
AND ord2.DM1 = ord3.DM1
AND ord2.prdcde = ord3.prdcde
AND ord2.stat = 16
AND opn2.samt < 0
GROUP BY ord2.DM1, ord2.prdcde
)) as foo
FROM PUB.ord ord3, PUB.opn opn3
WHERE
ord3.subsnum = opn3.subsnum
AND ord3.onum = opn3.onum
AND ord3.DM1 != ''
AND ord3.DM1 IN('XCWAJC25','WCWAMO73')
AND ord3.prdcde = 'CSC'
AND ord3.stat != 16
AND opn3.samt >= 0
GROUP BY ord3.DM1, ord3.prdcde
Thanks
I think this will work, although it would be nice to have sample data to verify:
SELECT COALESCE(SUM(a.samt), 0) - COALESCE(SUM(b.samt), 0)
+ COALESCE(SUM(CASE WHEN ord.stat = 16
AND b.samt < 0
THEN ord.samt END), 0)
FROM PUB.ord ord
LEFT JOIN PUB.opn a
ON a.subsnum = ord.subsnum
AND a.onum = ord.onum
AND a.samt >= 0
AND ord.stat != 16
LEFT JOIN PUB.opn b
ON b.subsnum = ord.subsnum
AND b.onum = ord.onum
AND b.samt < 0
AND ord.stat = 16
WHERE ord.DM1 IN('XCWAJC25', 'WCWAMO73')
AND ord.prdcde = 'CSC'
GROUP BY ord.DM1
Notes on query/stuff:
Always explicitly qualify joins, don't use the comma-separated FROM clause
I don't think you needed ord.DM1 != '', given that values have to be in a specific set
Putting a clause into a LEFT JOIN condition instead of the WHERE clause has a slightly different effect; it adds the condition to the join, instead of the filtering. This means that rows can be excluded based on something in the left table, regardless of whether you need the actual row (this is why ord.stat ended up in the LEFT JOINs). INNER JOINs would technically behave the same way, but it isn't usually noticeable because causing the right table to be excluded also excludes the left table.
I think this should do the trick, given the the individual queries work as intended:
SELECT sum1.tot + sum2.tot
FROM
(SELECT SUM(opn3.samt) as tot
FROM PUB.ord ord3, PUB.opn opn3
WHERE
ord3.subsnum = opn3.subsnum
AND ord3.onum = opn3.onum
AND ord3.DM1 != ''
AND ord3.DM1 IN('XCWAJC25','WCWAMO73')
AND ord3.prdcde = 'CSC'
AND ord3.stat != 16
AND opn3.samt >= 0
GROUP BY ord3.DM1, ord3.prdcde) sum1,
(SELECT SUM((-1 * opn2.samt) + ord2.samt) as tot
FROM PUB.ord ord2, PUB.opn opn2
WHERE
ord2.subsnum = opn2.subsnum
AND ord2.onum = opn2.onum
AND ord2.DM1 != ''
AND ord2.DM1 IN('XCWAJC25','WCWAMO73')
AND ord2.prdcde = 'CSC'
AND ord2.stat = 16
AND opn2.samt < 0
GROUP BY ord2.DM1, ord2.prdcde) sum2