Table ACCOUNT(Name, Debit, Credit)
Name | Debit | Credit
=========================
Ram | 2,000 | 2,000
Bheem | 3,000 | 3,000
Soorya | 2,500 | 1,750
John | 3,500 | 2,500
Abdul | 1,600 | 00000
Soorya | 1,500 | 00000
Table CLIENTS(Name, ContactNumber)
Name | ContactNumber
======================
Ram | 900800
Bheem | 900700
Soorya | 900600
John | 900400
Abdul | 900100
John | No Value
SQL
SELECT Name, SUM(Debit), SUM(Credit)
FROM ACCOUNT
WHERE SUM(Credit)<>SUM(Debit)
GROUP BY Name & ContactNumber
FROM CLIENTS WHERE ACCOUNT.Name=CLIENTS.Name
If the Name of client exists twice, Only the 1st ContactNumber should be selected.
Expected result:
Name | SUM(Debit) | SUM(Credit) | ContactNumber
==================================================
Soorya | 4,000 | 1,750 | 900600
John | 3,500 | 2,500 | 900400
Abdul | 1,600 | 0000 | 900100
How do I to sort this problem?
Not sure if this is the most elegant solution, but it gave the correct answer on the test data provided
WITH tmp
AS (SELECT Name,
Sum(Debit) AS SumDebit,
Sum(Credit) AS SumCredit
FROM accounts
GROUP BY Name)
SELECT a.Name,
a.SumDebit,
a.SumCredit,
c.ContactNumber
FROM tmp a,
(SELECT Name,
Max(ContactNumber) AS ContactNumber
FROM clients
GROUP BY Name) c
WHERE a.Name = c.Name
AND a.SumDebit <> a.SumCredit
Try using a JOIN statement, linked by the name fields.
SELECT a.Name, SUM(a.Debit), SUM(a.Credit), DISTINCT(c.ContactNumber)
FROM ACCOUNT a
WHERE SUM(a.Credit) != SUM(a.Debit)
INNER JOIN CLIENTS c
ON a.Name = c.Name
GROUP BY a.Name
Hope it helps.
Related
TABLE 1: Data sent to vendor
| MemberID | FirstName | LastName | Etc |
| :------: | :-------: | :------: | :-: |
| 1 | John | Smith | Etc |
| 2 | Jane | Doe | Etc |
| 3 | Dan | Laren | Etc |
TABLE 2: Data returned from vendor
| MemberID | FirstName | LastName | Etc |
| :------: | :-------: | :------: | :-: |
| 1 | John | Smith | Etc |
| 2 | Jane | Doe | Etc |
| 3 | Dan | Laren | Etc |
We send data to a vendor which is used for their matching algorithm and they return the data with new information. The members are matched with a MemberID data element. How would I write a query which shows me which MemberIDs we sent to the vendor but the vendor didn't return?
NOT EXITS would be my first choice here.
Example
SELECT *
FROM Table1 A
WHERE NOT EXISTS (SELECT 1
FROM Table2 B
WHERE A.MemberID = B.MemberID )
SELECT MemberID
FROM Table1
WHERE MemberID NOT IN (SELECT MemberID FROM Table2)
Using EXCEPT is one option.
SELECT sent.[MemberID] FROM Tbl1_SentToVendor sent
EXCEPT
SELECT recv.[MemberID] FROM Tbl2_ReturnedFromVendor recv
This is just on MemberID, but the "EXCEPT" syntax can also support additional columns (e.g., in case you want to filter out data that may be the same as what you already have.)
The following two tables Table 1 and Table 2 are given-
Table 1
+-----+------+---------+
| ID | Name | Earning |
+-----+------+---------+
| 101 | John | HRA |
| 101 | John | Travel |
| 102 | Andy | Travel |
+-----+------+---------+
Table 2
+-----+------+---------+
| ID | Name |Deduction|
+-----+------+---------+
| 101 | John | ENP |
| 102 | Andy | ENP |
| 102 | Andy | RA |
+-----+------+---------+
and I need to create a third table Table 3 with following columns
I have already created two columns ID and Name .I only need EarningOrDeduction column.
With
INSERT INTO Table3 (ID, Name, EarningOrDeduction)
SELECT ID, Name, Earning FROM Table1
UNION ALL
SELECT ID, Name, Deduction FROM Table2;
I'm getting
Table 3
+-----+------+------------------+
| ID | Name |EarningOrDeduction|
+-----+------+------------------+
| 101 | John | HRA |
| 101 | John | Travel |
| 102 | Andy | Travel |
| 101 | John | ENP |
| 102 | Andy | ENP |
| 102 | Andy | RA |
+-----+------+------------------+
But I want output as
Table 3
+-----+------+------------------+
| ID | Name |EarningOrDeduction|
+-----+------+------------------+
| 101 | John | HRA |
| 101 | John | Travel |
| 101 | John | ENP |
| 102 | Andy | Travel |
| 102 | Andy | ENP |
| 102 | Andy | RA |
+-----+------+------------------+
You can select both table data with Union clause.
And if you don't want to insert already entered values use following query.
INSERT INTO Table3 (EarningOrDeduction)
SELECT X FROM(
SELECT Earning X FROM Table1
UNION
SELECT Deduction X FROM Table2
) T
LEFT JOIN Table3 T3 ON T.X=T3.EarningOrDeduction
WHERE T3.EarningOrDeduction IS NULL
You could try inserting a union of values from the two tables:
INSERT INTO Table3 (ID, Name, EarningOrDeduction)
SELECT ID, Name, Earning FROM Table1
UNION ALL
SELECT ID, Name, Deduction FROM Table2;
Or, if you don't really want to populate Table3 with these values, you could just run the above select without the first insert line.
UNION ALL with Order by should work.
INSERT INTO Table3 (ID, Name, EarningOrDeduction)
SELECT ID, Name, EarningOrDeduction from
(SELECT ID, Name, Earning as [EarningOrDeduction] FROM Table1
UNION ALL
SELECT ID, Name, Deduction FROM Table2) ORDER BY ID, Name;
I assume Earnings and Deduction will not produce duplicate value for particular Name.
I have run into this scenario a couple of times, but it does not occur all the time on the same databases while testing. I have two separate databases I am merging into a single db both structured exactly the same. When inserting records from one database to the other, I am seeing distinct values duplicate on my target database however exist only once in one source and not in the target.
Example:
DB1..Customer
Cust_ID | Last_Name | First_Name | Phone | Email | Field1
1 | Smith | John | 111-1111 | m#M.com |
DB2..Customer
Cust_ID | Last_Name | First_Name | Phone | Email | Field1
1 | Jones | Steve | 222-2222 | S#S.com |
2 | Smith | Tom | 333-3333 | S#m.com |
When I run my query:
INSERT INTO DB1..Customer (Last_Name, First_Name, Phone, Email, Field1)
SELECT
Last_name, First_Name, Phone, Email, Cust_ID
FROM
DB2..Customer DB2
WHERE
DB2.Cust_ID NOT IN (SELECT DB2.Cust_ID
FROM DB2..Customer DB2
INNER JOIN DB1..Customer DB1 ON DB1.Last_Name = DB2.Last_Name
AND DB1.First_Name = DB2.First_Name
AND DB1.Email = DB2.Email)
Results:
DB1..Customer
Cust_ID | Last_Name | First_Name | Phone | Email | Field1
1 | Smith | John | 111-1111 | m#M.com |
2 | Jones | Steve | 222-2222 | S#S.com | 1
3 | Jones | Steve | 222-2222 | S#S.com | 1
4 | Jones | Steve | 222-2222 | S#S.com | 1
5 | Jones | Steve | 222-2222 | S#S.com | 1
6 | Smith | Tom | 333-3333 | S#m.com | 2
7 | Smith | Tom | 333-3333 | S#m.com | 2
8 | Smith | Tom | 333-3333 | S#m.com | 2
I notice duplicate values entered when I run a count on the field1 column having more than one count of db2..customer.cust_id. Since Cust_ID is the PK value I should only have one value flow into the field1 column per my query.
Any ideas or suggestions on why this may be occurring? My last run of my query duplicated some items up to 4 times. It seems to me SQL is caught in a bit of a loop searching for the patient while also writing them to the target db at the same time.
Left joining is a little slower, but easier to read and does what you want.
INSERT INTO DB1..Customer(
Last_Name
, First_Name
, Phone
, Email
, Field1)
SELECT
B.Last_name
, B.First_Name
, B.Phone
, B.Email
, B.Cust_ID
FROM
DB2..Customer B
LEFT JOIN
DB1..Customer A ON
A.Last_Name = B.Last_Name
AND
A.First_Name = B.First_Name
AND
A.Email = B.Email
AND
A.Phone = B.Phone
WHERE A.Cust_ID IS NULL;
Could you try changing the aliases used in the outer query and sub-query to be different? I don't have multiple instances at hand to test, but I wonder if it is being interpreted as a correlated subquery.
Try the following query, which uses DB1_Inner/DB2_Inner/DB2_Outer to differentiate the aliases:
Insert into DB1..Customer (Last_Name, First_Name, Phone, Email, Field1)
SELECT Last_name, First_Name, Phone, Email, Cust_ID
from DB2..Customer DB2_Outer
Where DB2_Outer.Cust_ID not in
(Select DB2_Inner.Cust_ID
from DB2..Customer DB2_Inner
Inner Join DB1..Customer DB1_Inner
on DB1_Inner.Last_Name=DB2_Inner.Last_Name
and DB1_Inner.First_Name=DB2_Inner.First_Name
and DB1_Inner.Email=DB2_Inner.Email)
I'm relatively new to SQL and am running into a lot of issues trying to figure this one out. I've tried using a LEFT JOIN, and dabbled in using functions to get this to work but to no avail.
For every UserID, if there is a NULL value, I need to remove all records of the Product ID for that UserID from my SELECT.
I am using SQL Server 2014.
Example Table
+--------------+-------------+---------------+
| UserID | ProductID | DateTermed |
+--------------+-------------+---------------+
| 578 | 2 | 1/7/2017 |
| 578 | 2 | 1/7/2017 |
| 578 | 1 | 1/15/2017 |
| 578 | 1 | NULL |
| 649 | 1 | 1/9/2017 |
| 649 | 2 | 1/11/2017 |
+--------------+-------------+---------------+
Desired Output
+--------------+-------------+---------------+
| UserID | ProductID | DateTermed |
+--------------+-------------+---------------+
| 578 | 2 | 1/7/2017 |
| 578 | 2 | 1/7/2017 |
| 649 | 1 | 1/9/2017 |
| 649 | 2 | 1/11/2017 |
+--------------+-------------+---------------+
Try the following:
SELECT a.userid, a.productid, a.datetermed
FROM yourtable a
LEFT OUTER JOIN (SELECT userid, productid, datetermed FROM yourtable WHERE
datetermed is null) b
on a.userid = b.userid and a.productid = b.productid
WHERE b.userid is not null
This will left outer join all records with a null date to their corresponding UserID and ProductID records. If you only take records that don't have an associated UserID and ProductID in the joined table, you should only be left with records that don't have a null date.
You can use this WHERE condition:
SELECT
UserID,ProducID,DateTermed
FROM
[YourTableName]
WHERE
(CONVERT(VARCHAR,UserId)+
CONVERT(VARCHAR,ProductID) NOT IN (
select CONVERT(VARCHAR,UserId)+ CONVERT(VARCHAR,ProductID)
from
[YourTableName]
where DateTermed is null)
)
When you concatenate the UserId and the ProductId get a unique value for each pair, then you can use them as a "key" to exclude the "pairs" that have the null value in the DateTermed field.
Hope this help.
I'm using SQL Server 2012. I have a table CustomerMaster. Here is some sample content:
+--------+---------------+-----------------+-------------+
| CustNo | NewMainCustNo | Longname | NoOfMembers |
+--------+---------------+-----------------+-------------+
| 3653 | 3653 | GroupId:003 | |
| 3654 | 3654 | GroupId:004 | |
| 11 | 3653 | Peter Evans | |
| 155 | 3653 | Harold Charley | |
| 156 | 3654 | David Arnold | |
| 160 | 3653 | Mickey Willson | |
| 2861 | 3653 | Jonathan Wickey | |
| 2871 | 3653 | William Jason | |
+--------+---------------+-----------------+-------------+
The NewMainCustNo for Customer records is equivalent to CustNo from Group records. Basically each customer belongs to a particular group.
My question is how to update the NoOfMembers column for group records with total number of customer belongs to a certain group.
Please share your ideas on how to do this.
Thank you...
This is the solution I came up with
update CustomerMaster
set NoOfMembers = (select count(*) from CustomerMaster m2 where m2.NewMainCustNo = CustomerMaster.CustNo and m2.CustNo <> CustomerMaster.CustNo)
where LongName like 'GroupId:%'
Check this SQL Fiddle to see the query in action.
However I disagree with your data structure. You should have a separate table for your groups. In your customer table you only need to reference the ID of the group in the group table. This makes everything (including the query above) much cleaner.
If I understand correctly, you can use a window function for the update. Here is an example with an updatable CTE:
with toupdate as (
select cm.*, count(*) over (partition by NewMainCustNo) as grpcount
from customermaster
)
update toupdate
set NoOfMembers = grpcount;
You may not have the option to do so, but I would separate groups out into their own table.
create table Groups (
GroupID int primary key,
Name varchar(200)
)
Then, change NewMainCustNo to GroupID, create, purge your customer table of groups, and go from there. Then, getting a group count would be:
select GroupID,
Name [Group Name],
COUNT(*)
from Groups g
join Customers c on
c.GroupID = g.GroupID