I have two tables as below. The Id column value in both the tables mentioned below is auto-incremented.
Group
+----+-----------+----------------+
| Id | GroupId | GroupName |
+----+-----------+----------------+
| 1 | 10 | Grp1#abc.com |
| 2 | 20 | Grp2#abc.com |
| 3 | 30 | Grp3#xyz.com |
| 4 | 40 | Grp4#def.com |
+----+-----------+----------------+
Customer
+---+-----------------+------------+----------+---------------+
| Id | GroupAliasName | Domain | GroupId | CustomerName |
+---+-----------------+------------+----------+---------------+
| 1 | Grp1 | abc.com | null | Cust1 |
| 2 | Grp2 | abc.com | null | Cust2 |
| 3 | Grp3 | xyz.com | null | Cust3 |
| 4 | Grp4 | def.com | null | Cust4 |
+---+-----------------+------------+----------+---------------+
Now from Customer table 'GroupAliasName' and 'Domain' when concatenated as 'GroupAliasName#Domain' is equivalent to 'GroupName' in Group table.
Using the concatenated value from Customer table, I need to pull the 'GroupId' from the Group table and populate the same in Customer table's 'GroupId' as below
Customer
+----+----------------+------------+----------+---------------+
| Id | GroupAliasName | Domain | GroupId | CustomerName |
+----+----------------+-----------+---------+-----------------+
| 1 | Grp1 | abc.com | 10 | Cust1 |
| 2 | Grp2 | abc.com | 20 | Cust2 |
| 3 | Grp3 | xyz.com | 30 | Cust3 |
| 4 | Grp4 | def.com | 40 | Cust4 |
+----+----------------+------------+----------+---------------+
The query which I tried is as below
UPDATE Customer SET GroupId =
(SELECT GroupId FROM Group G
WHERE GroupName =
(SELECT CONCAT(GroupAliasName, '#', Domain) AS GroupName
FROM Customer
WHERE Domain IS NOT NULL) AND G.GroupName = GroupName);
But I get error as 'Subquery returns more than 1 row'.
Please suggest or provide your inputs.
Try this:
update customer as cust
inner join `group` grp on concat(cust.groupaliasname, '#', cust.domain) = grp.groupname
set cust.groupId = grp.groupId;
Try with somethings like this
UPDATE Customer as c
INNER JOIN Group as g on ( CONCAT(c.GroupAliasName, '#', c.Domain) = g.GroupName)
SET c.GroupId = g.GroupId;
Related
I have 3 tables, which every table has it's own foreign key and primary key.
Table scheme looks like this :
tbl_cake
/---------------------------------------------------------------------------\
| CakeId (Primary key) | CakeName | UserId (Foreign Key from tbl_user) |
|----------------------------------------------------------------------------|
| 1 | BlackForest | 12345 |
|----------------------------------------------------------------------------|
| 2 | Fruit Pie | 98475 |
|----------------------------------------------------------------------------|
| 3 | Birthday Cake | 12345 |
|----------------------------------------------------------------------------|
| 4 | Raspberry Pie | 28475 |
\----------------------------------------------------------------------------/
tbl_user
/--------------------------------------\
| UserId (Primary key) | UserName |
|--------------------------------------|
| 12345 | Angelia |
|--------------------------------------|
| 98475 | Rudi |
|--------------------------------------|
| 56782 | Andika |
\--------------------------------------/
tbl_transaction
/--------------------------------------------------------------------------------------------------\
| TransactionId(Primary) | CakeId(Foreign) | UserId| Qty | Date | OrderType |
|--------------------------------------------------------------------------------------------------|
| 1 | 1 | 12345 | 1000 | 2020-04-01 10:05:01 | Drive Thru |
|--------------------------------------------------------------------------------------------------|
| 2 | 2 | 98475 | 200 | 2020-04-03 09:15:01 | On The Spot |
|--------------------------------------------------------------------------------------------------|
| 3 | 2 | 98475 | 500 | 2020-04-03 11:05:01 | On The Spot |
|--------------------------------------------------------------------------------------------------|
| 4 | 1 | 12345 | 150 | 2020-04-05 08:05:01 | On The Spot |
\--------------------------------------------------------------------------------------------------/
So the goals are :
Show UserId,TransactionId,Qty,Date and OrderType which :
Show all UserId, either it has any order or not.
If multiple order occurs, then show the latest data
If UserId don't have any order, fill the missing values with null
Finally, show the data with OrderType 'On The Spot'.
The expected result will be :
FINAL RESULT
/----------------------------------------------------------------------------------\
| UserId | TransactionId | Qty | Date | OrderType |
|----------------------------------------------------------------------------------|
| 12345 | 4 | 150 | 2020-04-05 08:05:01 | On The Spot|
|----------------------------------------------------------------------------------|
| 98475 | 3 | 500 | 2020-04-03 11:05:01 | On The Spot|
|----------------------------------------------------------------------------------|
| 56782 | null | null | null | null |
\----------------------------------------------------------------------------------/
I think using join(s) will accomplish this, but i'm not sure how, especially when determine if UserId has any order or not, and pick the latest order to be shown.
Many thanks!
In MySQL 8+, we would use ROW_NUMBER here:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY Date DESC) rn
FROM tbl_transaction
WHERE OrderType = 'On The Spot'
)
SELECT
u.UserId,
t.TransactionId,
t.Qty,
t.Date,
t.OrderType
FROM tbl_user u
LEFT JOIN cte t
ON u.UserId = t.UserId AND rn = 1;
Demo
I managed to solve it (using left join and max function) :
select tbl_user.UserId,tbl_transaction.TransactionId,tbl_transaction.Qty,tbl_transaction.Date,
tbl_transaction.OrderType
from tbl_cake
left join tbl_user on tbl_user.UserId=tbl_cake.UserId
left join tbl_transaction on tbl_user.UserId=tbl_transaction.UserId
and
tbl_transaction.Date=(select max(Date) from tbl_transaction where UserId=tbl_User.UserId
and tbl_transaction.OrderType="On The Spot")
group by UserId
i would like to get the Count value from the 3rd table... 1st table has reference id to 2nd table, 2nd table has reference id of 3rd table... in 3rd table has the value... that i need to count...
Table struct:
table1: tbl_rack
+------------+---------+--------+
| rack_id | site_id | status |
+------------+---------+--------+
| R-642 | ST5 | Y |
| R-307 | ST6 | Y |
| R-57 | ST7 | Y |
| 390/6 | ST8 | Y |
| 9706 | ST11 | Y |
table2: tbl_site
+---------+-------------+-----------+
| site_id | customer_id | region_id |
+---------+-------------+-----------+
| ST5 | CM8 | RM4 |
| ST6 | CM8 | RM8 |
| ST7 | CM10 | RM2 |
| ST8 | CM11 | RM12 |
| ST11 | CM8 | RM10 |
table3: tbl_customer
+-------------+----------------------+---------------+
| customer_id | customer_name | customer_type |
+-------------+----------------------+---------------+
| CM8 | LIVI-IN | MODERATE |
| CM10 | PEPE | HIGH |
| CM11 | SANDER | LOW |
| CM12 | TOASTER | MODERATE |
I want to count each customers contains how many Racks where ranks status is 'Y'
expected Result1:
Customer No.of Racks
LIVI-IN 3
OTHERS 2
expected Result2:
Customer Type No.of Racks
Moderate 3
High 1
Low 1
Please, follow below SQL query:
select C.customer_name as 'Customer', count(*) as 'No.of Racks'
from tbl_customer C
left outer join tbl_site TS on TS.customer_id = C.customer_id
left outer join tbl_rack TR on TR.site_id = TS.site_id
group by C.customer_name
order by C.customer_name
I have a table called users, another table called withdraws,
How do I select a row for each withdraw request from the user with his bank details which are in the users table.
IMPORTANT : user_name in users table is unique for each row. this is corresponding to the userid in withdraws table
Here is,
Users Table
+-----------+-----------------+-------------+
| user_name | bank_ac | ifsc |
+-----------+-----------------+-------------+
| H6426012 | 456456 | ifsc6544 |
+-----------+-----------------+-------------+
Withdraws Table
+----------+--------+--------+
| userid | amount | status |
+----------+--------+--------+
| H6426012 | 300.00 | 1 |
| H6426012 | 150.00 | 1 |
| H6426012 | 200.00 | 1 |
+----------+--------+--------+
Here is the query I am using :
select withdraws.userid
, withdraws.amount
, users.user_name
, users.ifsc
, users.bank_ac
from withdraws
JOIN users
on withdraws.userid = users.user_name
where withdraws.status = 1
This is the result I am expecting :
I am expecting this result
+----------+--------+--------++----------+--------+--------+
| userid | amount | status |user_name | ifsc | bank_ac |
+----------+--------+--------++----------+--------+--------+
| H6426012 | 300.00 | 1 | H6426012 | ifsc6544 | 456456 |
| H6426012 | 150.00 | 1 | H6426012 | ifsc6544 | 456456|
| H6426012 | 200.00 | 1 | H6426012 | ifsc6544 | 456456 |
+----------+--------+--------++----------+--------+--------+
BUT I am getting this result
+----------+--------+--------++----------+--------+--------+
| userid | amount | status |user_name | ifsc | bank_ac |
+----------+--------+--------++----------+--------+--------+
| H6426012 | 300.00 | 1 | NULL | NULL | NULL |
| H6426012 | 150.00 | 1 | NULL | NULL | NULL|
| H6426012 | 200.00 | 1 | NULL | NULL | NULL |
+----------+--------+--------++----------+--------+--------+
I ran the same query and it worked just fine, I also created the same query but without any joins, and it worked as well...
I am using SQL Server Management Studio V17.9.
First change user_name to user_id on your users schema/table so as it will not confuse you in future. and then, modify your query like below then it will work fine
select users.userid as user_id,
withdraws.amount as amount,
withdraws.status as status
users.ifsc as ifsc
users.bank_ac as bank_ac
from withdraws
JOIN users
on withdraws.userid = users.userid
where withdraws.status = 1
I have some tables from which I need to get data.
Here is my structure:
employees
| id | name |
+----+---------+
| 1 | Michael |
| 2 | Sarah |
reports
| id | employee_id | month | year | value | group_id |
+----+-------------+-------+------+-------+----------+
| 1 | 1 | 01 | 2018 | 35 | 1 |
| 2 | 1 | 02 | 2018 | 12 | 1 |
| 3 | 2 | 02 | 2018 | 2 | 2 |
groups
| id | name | employee_id |
+----+------+-------------+
| 1 | G11 | 1 |
| 2 | Z15 | 2 |
Now I need to get groups with employee WHERE employee with group_id AND month AND year DON'T HAVE REPORT, eg.
When I look for 01.2018, it should returns me only Z15 but when I look for 04.2018 it should return Z15 and G11.
How can I do this? At this moment I have sth like this:
SELECT
groups.*,
employees.*,
-- all fields from reports
FROM
groups
INNER JOIN
employees
ON
employees.id = groups.employee_id
My column names are slightly different from yours. That's deliberate...
SELECT g.*
FROM groups g
LEFT
JOIN reports r
ON r.group_id = g.group_id
AND r.yearmonth = 201801
WHERE r.report_id IS NULL;
Kindly consider the following tables:
invoices
+-----------+----+------------+--------+---------+
| accountid | id | customerid | total | balance |
+-----------+----+------------+--------+---------+
| 1 | 2 | 167909 | 120060 | 120060 |
+-----------+----+------------+--------+---------+
invoices_attributes
+-----------+----+--------------+
| accountid | id | name |
+-----------+----+--------------+
| 1 | 1 | registration |
+-----------+----+--------------+
| 1 | 2 | claimnumber |
+-----------+----+--------------+
| 1 | 3 | jobid |
+-----------+----+--------------+
invoices_attributes_values
+------------------+-------------+-----------+---------------+
| attributevalueid | attributeid | invoiceid | value |
+------------------+-------------+-----------+---------------+
| 1 | 1 | 2 | ABC 126L |
+------------------+-------------+-----------+---------------+
| 2 | 2 | 2 | ABZ123 |
+------------------+-------------+-----------+---------------+
| 3 | 3 | 2 | MARY DOE |
+------------------+-------------+-----------+---------------+
Through the help of Eugen Rieck's original answer I was able to make the following query
SELECT
invoices.accountid,
invoices.id AS invoiceid,
invoices.customerid,
invoices.total,
registration.value AS registration,
claimnumber.value AS claimnumber,
jobid.value as jobid
FROM
invoices
LEFT JOIN invoice_attributes ON invoices.accountid=invoice_attributes.accountid
LEFT JOIN invoice_attribute_values AS registration ON registration.attributeid = invoice_attributes.id AND invoices.id = registration.invoiceid AND invoice_attributes.name = 'registration'
LEFT JOIN invoice_attribute_values AS claimnumber ON claimnumber.attributeid = invoice_attributes.id AND invoices.id = claimnumber.invoiceid AND invoice_attributes.name = 'claimnumber'
LEFT JOIN invoice_attribute_values AS jobid ON jobid.attributeid = invoice_attributes.id AND invoices.id = jobid.invoiceid AND invoice_attributes.name = 'jobid'
Which gave the following result
+-----------+-----------+------------+--------+--------------+-------------+----------+
| accountid | invoiceid | customerid | total | registration | claimnumber | jobid |
+-----------+-----------+------------+--------+--------------+-------------+----------+
| 1 | 2 | 167909 | 120060 | NULL | NULL | MARY DOE |
+-----------+-----------+------------+--------+--------------+-------------+----------+
| 1 | 2 | 167909 | 120060 | NULL | ABZ123 | NULL |
+-----------+-----------+------------+--------+--------------+-------------+----------+
| 1 | 2 | 167909 | 120060 | ABC 126L | NULL | NULL |
+-----------+-----------+------------+--------+--------------+-------------+----------+
When I GROUP BY invoices.id some of the columns (registration, claimnumner or job) will become NULL. I desire the result to be as:
+-----------+-----------+------------+--------+--------------+-------------+----------+
| accountid | invoiceid | customerid | total | registration | claimnumber | jobid |
+-----------+-----------+------------+--------+--------------+-------------+----------+
| 1 | 2 | 167909 | 120060 | ABC 126L | ABZ123 | MARY DOE |
+-----------+-----------+------------+--------+--------------+-------------+----------+
How can the query be modified to get the result above?
SQL has no provision to make the columns dependant on the data. You could however create a query with ALL possible attributes along the lines of
Basically you want to renormalize an EVA structure - this is of course possible:
SELECT
invoices.accountid,
invoices.id AS invoiceid
invoices.customerid,
invoices.total,
jobids.value AS jobid -- one of these lines per attriubute
FROM
invoices
LEFT JOIN invoices_attributes ON invoices.accountid=invoices_attributes.accountid
-- One of the following joins per attribute
LEFT JOIN invoices_attributes_values AS jobids
ON jobids.attr_id=invoices_attributes.attr_id
AND jobids.accountid=invoices.accountid
AND jobids.invoiceid=invoices.id
AND invoices_attributes.attr_name='jobid'