Count and return where 2 fields match - sql

I'm trying to write a script that counts results based on 2 fields matching - but not matching like identically, but where the values re-occur throughout the table.
For example, I want to find where Field A and Field B = x & y, respectively (and count those results) however, field A isn't always X and field B isn't always Y. Also, Field A and Field B values are unknown. Here's what I've written so far:
select a.fielda, b.fieldb, count (*)
from tableA a
join tableB b
on a.fieldd = b.fieldd
where a.fielda = b.fieldb --I know this is a problem, just for notes on what I'm trying to accomplish.
group by b.fieldb, a.fielda
order by b.fieldb.
I'm a newb here so any help will be greatly appreciated. Thank you in advance.

SELECT SUM(CASE WHEN a.fielda = b.fieldb THEN 1 ELSE NULL END) AS MatchCount
, SUM(CASE WHEN a.fielda = x and b.fieldb = y THEN 1 ELSE NULL END) AS XYCount
, COUNT(*) AS FieldDMatchCount
FROM tableA a
JOIN tableB b
ON a.fieldd = b.fieldd

Tobsey had it correct for me. I didn't think that by selecting the two fields that I was already finding records where those two fields existed together...brain fart, I guess. Thank you for the help!

Related

Join two tables on multiple conditions Using Oracle SQL

I have a 2 Tables with below structures
Table 1-- Containing Values like this.
OTHER_CODE
CAPACITY_CODE
Result
A
1
A
5
A
9
A
(null)
B
2
B
6
B
2
Table_2- With Values Like
OTHER_CODE
CAPACITY_CODE
Result
A
1
A
A
5
B
A
(null)
C
A
ELSE
D
B
ALL
E
(null)
ALL
F
I need to Join Table_1 with Table_2 on basis of columns OTHERCODE and CAPACITYCODE and update values in Column Result of Table**1 **using a Merge statement.
I need to handle and match Values based on ELSE and ALL values too.
Check for Direct Match
Check if ALL or ELSE condition
The Final TABLE_1 must look like
OTHER_CODE
CAPACITY_CODE
Result
Explanation
A
1
A
Direct Join
A
5
B
Direct Join
A
9
D
Satsifying ELSE condition
A
(null)
C
Direct join with NVL handling
B
2
E
As Value for CapacityCode in TableB is ALL
B
6
E
As Value for CapacityCode in TableB is ALL
B
2
E
As Value for CapacityCode in TableB is ALL
I Tried Joining both the tables but the was unable to satisfy Else and ALL conditions. Hope if someone can help me on this.
There are Several **Result ** Columns like , Result 1 ,2 in both tables which needs to be updated using the same logic.
Thanks in Advance.
here is a fiddle to work on https://dbfiddle.uk/FMKdWzQT
I got the query working. by using a case statement and assigning a number so I could use max then I just remove the number.
SELECT a.other_code,
a.capacity_code,
(
SELECT SUBSTR(max(
CASE WHEN b.other_code = a.other_code AND a.capacity_code = b.capacity_code THEN concat('3',b.myresult)
WHEN b.other_code = a.other_code AND a.capacity_code is null and b.capacity_code is null THEN concat('2',b.myresult)
WHEN b.other_code = a.other_code AND b.capacity_code in ('ELSE', 'ALL') THEN concat('1',b.myresult)
else null end),2)
FROM table2 b ) as myresult
FROM table1 a
however I can not get the update to work. I tried a merge it is give me the unstable row error and I tried an update select but that is giving me single row subquery error so maybe someone else can take a look at the fiddle. here was my attempt at the update.
UPDATE table1
SET myresult = (
SELECT myresult
FROM (
SELECT a.other_code,
a.capacity_code,
(
SELECT SUBSTR(max(
CASE WHEN b.other_code = a.other_code AND a.capacity_code = b.capacity_code THEN concat('3',b.myresult)
WHEN b.other_code = a.other_code AND a.capacity_code is null and b.capacity_code is null THEN concat('2',b.myresult)
WHEN b.other_code = a.other_code AND b.capacity_code in ('ELSE', 'ALL') THEN concat('1',b.myresult)
else null end),2)
FROM table2 b ) as myresult
FROM table1 a
)t2
WHERE table1.other_code = t2.other_code and nvl(table1.capacity_code,'x') = nvl(t2.capacity_code,'x')
);

Assigning a numeric score to a group of SQL statements

I was hoping someone could help me with the best way to do this in SQL.
If I have about 5 select statements
e.g.,
1) select name from payment a
join address b on a.id = b.id (if this statement score = 4)
2) select name from payment x
join address y on x.id = y.id (if this statement score = 7)
What is the best logic to use to know which select the person belongs to and how do I assign a numeric value to that name
If am not wrong you are looking for something like this
SELECT CASE
WHEN statement_score = 4 THEN 'statement_score_4'
WHEN statement_score = 7 THEN 'statement_score_7'
.....
END AS identifier,
name
FROM payment a
JOIN address b
ON a.id = b.id
AND statement_score IN( 4, 7,.. )
I don't know if I totally understand your question, but maybe you can select a value in each SELECT statement that indicates which query it came from. In other words,
select name, 4 AS score from payment a join address b on a.id = b.id (if this statement score = 4)
select name, 7 AS score from payment x join address y on x.id = y.id (if this statement score = 7)

SQL CASE on selected column in the same select

I am constructing a large table where I need to use CASE several places in the same select. The problem arises when I need to use an already selected column in a CASE in the same select. Example:
SELECT CASE WHEN (B.field_B1 + C.field_C1) > x THEN x ELSE 0 END AS field_1,
CASE WHEN field_1 > y THEN 'larger' ELSE 'smaller' END AS field 2,
CASE WHEN field_1 > z THEN 'taller' ELSE 'shorter' END AS field 3
FROM table_A AS A
INNER JOIN table_B as B on A.key_1 = B.KEY_1
LEFT OUTER JOIN table_C as C on A.key_1 = C.KEY_1
The table of interest consists of a few hundred columns and several million rows, so performance is a key issue here. CROSS APPLY is not supported in this case, and I would like to avoid WITH before the SELECT as this is a small part of a large script. Any creative ideas?

sqlite extra column with 1 and 0 if record exists in related table or not

I am not so good at SQL, so I have the following tables
Stuff
and
Specialty
Let's say, the worker with name 'Bob' has two specialties. How could I get the specialty table with an extra column (let's say count) which has 1 if the record exists in Stuff and 0 otherwise.
I would like to ask if there is any way to cast a query
that returns a result for Bob as shown below?
Any suggestions would be very helpful. Thank you in advance.
(I am not sure about the title. Please do suggest if you have a better idea!)
I would be inclined to do this with a case and exists:
select sp.*,
(case when exists (select 1
from stuff s
where s.surname = 'Bob' and
s.speciality_code = sp.speciality_code
)
then 1 else 0
end) as BobHas
from specialty sp;
Use Left Outer join with Null check. Try this.
SELECT sp.specialitycode,
sp.description,
CASE
WHEN st.specialitycode IS NULL THEN 0
ELSE 1
END AS count
FROM speciality sp
LEFT OUTER JOIN (SELECT specialitycode
FROM stuff
WHERE surname = 'Bob') st
ON sp.specialitycode = st.specialitycode

Join Table on one record but calculate field based on other rows in the join

I am trying to write a query to Identify my subscribers who have abandoned a shopping cart in the last day but also I need a calculated field that represents weather or not they have received and incentive in the last 7 days.
I have the following tables
AbandonCart_Subscribers
Sendlog
The first part of the query is easy, get abandoners in the last day
select a.* from AbandonCart_Subscribers
where DATEDIFF(day,a.DateAbandoned,GETDATE()) <= 1
Here is my attempt to calculate the incentive but I am fairly certain it is not correct as IncentiveRecieved is always 0 even when I know it should not be...
select a.*,
CASE
WHEN DATEDIFF(D,s.SENDDATE,GETDATE()) >= 7
THEN 1
ELSE 0
END As IncentiveRecieved
from AbandonCart_Subscribers a
left join SendLog s on a.EmailAddress = s.EmailAddress and s.CampaignID IS NULL
where
DATEDIFF(day,a.DateAbandoned,GETDATE()) <= 1
Here is a SQL fiddle with the objects and some data. I would really appreciate some help.
Thanks
http://sqlfiddle.com/#!3/f481f/1
Kishore is right in saying the main problem is that it should be <=7, not >=7. However, there is another problem.
As it stands, you could get multiple results. You don't want to do a left join on SendLog in case the same email address is in there more than once. Instead you should be getting a unique result from that table. There's a couple of ways of doing that; here is one such way which uses a derived table. The table I have called s will give you a unique list of emails that have been sent an incentive in the last week.
select a.*,
CASE
WHEN s.EmailAddress is not null
THEN 1
ELSE 0
END As IncentiveRecieved
from AbandonCart_Subscribers a
left join (select distinct EmailAddress
from SendLog s
where s.CampaignID IS NULL
and DATEDIFF(D,s.SENDDATE,GETDATE()) <= 7
) s on a.EmailAddress = s.EmailAddress
where DATEDIFF(day,a.DateAbandoned,GETDATE()) <= 1
You can set a variable using a condition:
select a.*,(DATEDIFF(D,s.SENDDATE,GETDATE()) >= 7) as `IncentiveRecieved `
from AbandonCart_Subscribers a
left join SendLog s on a.EmailAddress = s.EmailAddress and s.CampaignID IS NULL
where
DATEDIFF(day,a.DateAbandoned,GETDATE()) <= 1
Is this what you're looking for?
should it not be less than 7 instead of greater than 7?
select a.*,
CASE
WHEN DATEDIFF(D,s.SENDDATE,GETDATE()) <= 7 AND CampaignID is not null
THEN 1
ELSE 0
END As IncentiveRecieved
from AbandonCart_Subscribers a
left join SendLog s on a.EmailAddress = s.EmailAddress --and s.CampaignID IS NULL
where
DATEDIFF(day,a.DateAbandoned,GETDATE()) <= 1
Hope this satisfies your need.