I want to add an amount to the rows returned from a select. I've been trying things along the lines of:
select *,
3 as amount
from products
where etc....
...and it works. However, I want to do the same thing for lots of rows in one go along the lines of:
select *,
3 as amount,
2 as amount,
4 as amount
from products
where id in ('1','2','3')
However this keeps adding amount columns and not changing the values in each row returned.
The amount is really an amount the users wants, it could be 1-99-4-2 or any number. I wanted to get a table with the results like: products amount --------------------------- ... 1 ... 99 ... 4 ... 2 I just wanted all the mount in one column thats why I was using select ? as amount select ? as amount but it just doesn't seem to work that way :-)
SELECT id, ELT(id, 3, 2, 4) AS amount
FROM products
WHERE id IN ('1', '2', '3')
Try with:
SELECT *, 3 AS amt1, 2 AS amt2, 4 AS amt3 FROM products WHERE id IN ('1','2','3')
Give each alias a unique name. For example, amount1, amount2, etc.
EDIT> If you'd like sum of the columns, use SELECT SUM(amount1, amount2, amount3, ...) FROM ...
Related
I have a table as follows
groupCode
ProductIdentifier
1
dental
1
membership
2
dental
2
vision
2
health
3
dental
3
vision
I need to find out if a specific groupCode have "dental", "vision" and "health" (all three simultaneously)
The expected result is code 2
What I need to identify is if groupCode 2 has the three products (or two, or whatever the user enters). This is part of a huge kitchen sink query I'm building.
I'm doing
SELECT groupCode
FROM dbo.table
WHERE (productIdentifier = N'dental')
AND (productIdentifier = N'vision')
AND (productIdentifier = N'health')
AND (groupCode = 2)
But clearly is wrong because it's not working.
I tried to do something like its described here but it didn't return a result for me:
Select rows with same id but different value in another column
Thanks.
If each of 'dental','vision' and 'health' occur only once per group identifier, you can group by group identifier and filter by the groups having count(*) = 3:
WITH
-- your input ..
indata(groupCode,ProductIdentifier) AS (
SELECT 1,'dental'
UNION ALL SELECT 1,'membership'
UNION ALL SELECT 2,'dental'
UNION ALL SELECT 2,'vision'
UNION ALL SELECT 2,'health'
UNION ALL SELECT 3,'dental'
UNION ALL SELECT 3,'vision'
)
-- real query starts here ...
SELECT
groupcode
FROM indata
WHERE productidentifier IN ('dental','vision','health')
GROUP BY
groupcode
HAVING COUNT(*) = 3;
-- out groupcode
-- out -----------
-- out 2
As per Marcothesane answer, if you know the groupCode (2) and the number of products (vision, dental and health), 3 in this case, and you need to confirm if that code has those three specific products, this will work for you:
SELECT COUNT(groupCode) AS totalRecords
FROM dbo.table
WHERE (groupCode = 2) AND (productIdentifier IN ('dental', 'vision', 'health'))
HAVING (COUNT(groupCode) = 3)
This will return 3 (number of records = number of products).
Its basically's Marcothesane answer in a way you can "copy/paste" to your code by just changing the table name. You should accept Marcothesane answer.
I would like to ignore some of the results of my query as for all intents and purposes, some of the results are a duplicate, but based on the way the request was made, we need to use this hierarchy and although we are seeing different 'Company_Name' 's, we need to ignore one of the results.
Query:
SELECT
COUNT(DISTINCT A12.Company_name) AS Customer_Name_Count,
Company_Name,
SUM(Total_Sales) AS Total_Sales
FROM
some_table AS A12
GROUP BY
2
ORDER BY
3 ASC, 2 ASC
This code omits half a doze joins and where statements that are not germane to this question.
Results:
Customer_Name_Count Company_Name Total_Sales
-------------------------------------------------------------
1 3 Blockbuster 1,000
2 6 Jimmy's Bar 1,500
3 6 Jimmy's Restaurant 1,500
4 9 Impala Hotel 2,000
5 12 Sports Drink 2,500
In the above set, we can see that numbers 2 & 3 have the same count and the same total_sales number and similar company names. Is there a way to create a case statement that takes these 3 factors into consideration and then drops one or the other for Jimmy's enterprises? The other issue is that this has to be variable as there are other instances where this happens. And I would only want this to happen if the count and sales number match each other with a similar name in the company name.
Desired result:
Customer_Name_Count Company_Name Total_Sales
--------------------------------------------------------------
1 3 Blockbuster 1,000
2 6 Jimmy's Bar 1,500
3 9 Impala Hotel 2,000
4 12 Sports Drink 2,500
Looks like other answers are accurate based on assumption that Company_IDs are the same for both.
If Company_IDs are different for both Jimmy's Bar and Jimmy's Restaurant then you can use something like this. I suggest you get functional users involved and do some data clean-up else you'll be maintaining this every time this issue arise:
SELECT
COUNT(DISTINCT CASE
WHEN A12.Company_Name = 'Name2' THEN 'Name1'
ELSE A12.Company_Name
END) AS Customer_Name_Count
,CASE
WHEN A12.Company_Name = 'Name2' THEN 'Name1'
ELSE A12.Company_Name
END AS Company_Name
,SUM(A12.Total_Sales) AS Total_Sales
FROM some_table er
GROUP BY CASE
WHEN A12.Company_Name = 'Name2' THEN 'Name1'
ELSE A12.Company_Name
END
Your problem is that the joins you are using are multiplying the number of rows. Somewhere along the way, multiple names are associated with exactly the same entity (which is why the numbers are the same). You can fix this by aggregating by the right id:
SELECT COUNT(DISTINCT A12.Company_name) AS Customer_Name_Count,
MAX(Company_Name) as Company_Name,
SUM(Total_Sales) AS Total_Sales
FROM some_table AS A12
GROUP BY Company_id -- I'm guessing the column is something like this
ORDER BY 3 ASC, 2 ASC;
This might actually overstate the sales (I don't know). Better would be fixing the join so it only returned one name. One possibility is that it is a type-2 dimension, meaning that there is a time component for values that change over time. You may need to restrict the join to a single time period.
You need to have function to return a common name for the companies and then use DISTINCT:
SELECT DISTINCT
Customer_Name_Count,
dbo.GetCommonName(Company_Name) as Company_Name,
Total_Sales
FROM dbo.theTable
You can try to use ROW_NUMBER with window function to make row number by Customer_Name_Count and Total_Sales then get rn = 1
SELECT * FROM (
SELECT *,ROW_NUMBER() OVER(PARTITION BY Customer_Name_Count,Total_Sales ORDER BY Company_Name) rn
FROM (
SELECT
COUNT(DISTINCT A12.Company_name) AS Customer_Name_Count,
Company_Name,
SUM(Total_Sales) AS Total_Sales
FROM
some_table AS A12
GROUP BY
Company_Name
)t1
)t1
WHERE rn = 1
I am trying to create a query that will select a list of items that have the same information in all the columns except 1, a Total # of Units. I need the query to combine those rows.
Example Columns
In the table I have 3 rows that look like this:
Date item # Description qty
---------------------------------
20150910 1233 lettuce 1.20
20150910 1234 cheese 3.40
20150910 1234 cheese 2.65
20150910 1234 cheese 1.00
I want to run an update query to update the table to look like this:
20150910, 1233, lettuce, 1.20
20150910, 1234, cheese, 7.05
Your help is appreciated!
It is just a grouped summation, except that you want to do the deletion. Instead of deleting the old rows, it is actually easier to just insert the data into a new table with the same schema, or rename the existing table to Table_Old.
You can then select the summary data from the old table with:
SELECT Code, Id, Description, SUM(Amount)
FROM Table
GROUP BY Code, Id, Description
This way you also have the old data as a backup, in case you mess it up! :)
You just need to sum qty
SELECT Date, Item, Description, SUM(qty)
FROM your_table
GROUP BY Date, Item, Description
Edit: For updating the table, assuming you have no negative values in qty, I'd do
UPDATE your_table yt
SET yt.qty = (SELECT SUM(yt2.qty)
FROM your_table yt2
WHERE yt.date = yt2.date and yt.Item=yt2.Item AND yt.Description = yt2.Description);
DELETE FROM your_table yt
WHERE qty <> (SELECT MAX(yt2.qty)
FROM your_table yt2
WHERE yt.date = yt2.date and yt.Item=yt2.Item AND yt.Description = yt2.Description);
This should do the trick, first you sum it and then delete every row that has qty different from the one you have just sumed.
Note that you don't need to group by in the subqueries as you're filtering the items you are updating/deleting
I have a SQL question from one of the well known IT company couple month ago when they were interviewing me, and I never got it figured out.
An order can have multiple lines - For ex., if a customer ordered cookies,
chocolates, and bread, this would count as 3 lines in one order. The question
is to find the number of orders in each line count. The output of this query
would be something like 100 orders had 1 line, 70 orders had 2 lines, 30 had 3
lines, and so on. This table has two columns - order_id and line_id
Sample Data:
order_id line_id
1 cookies
1 chocolates
1 bread
2 cookies
2 bread
3 chocolates
3 cookies
4 milk
desired output:
orders line
1 1
2 2
1 3
So generally speaking, we have a very large data set, and the line_id per order_id can be ranging from 1 to infinite(Theoretically speaking).
The desired output for the general case is:
orders line
100 1
70 2
30 3
etc..
How can I write a query to find the total number of orders per line count=1,2,3... etc
My thought on this problem is to first subquery the count of line_id per order_id.
And then select the subquery along with a list of values as the second column ranging from 1 to max(lines_id per order)
Test Data:
create table data
(
order_id int,
line_id char(50)
);
insert into data
values(1, 'cookies'),
(1, 'chocolates'),
(1, 'bread'),
(2, 'bread'),
(2, 'cookies'),
(3, 'chocolates'),
(3, 'cookies'),
(4, 'milk');
Since order_id=1 has 3 lines,
order_id=2 has 2 lines,
order_id=3 has 2 lines,
order_id=4 has 1 line.
Thus it yield our solution:
orders line
1 1
2 2
1 3
This is because both order_id = 2 and 3 has 2 lines. So it would mean 2 orders has line = 2.
So far, I have:
select lines,
sum(case when orders_per_line = '1' then 1 else 0),
sum(case when orders_per_line = '2' then 1 else 0),
sum(case when orders_per_line = '3' then 1 else 0)
from(
select lines, order_id, count(*) as orders_per_line from data
where lines in ('1, '2', '3')
group by order_id, lines
)
group by lines
My query is wrong, as I only want 2 columns, and also creating a sequence of numbers ranging from 1 to max(lines per order) is also wrong.
Any suggestions?
Thanks in advance!
Try this:
Select Count(*) as Orders, Lines from (
Select order_id, Count(*) as Lines from data group by order_id
)query group by Lines
For exmaple, look at this sqlfiddle
Try This:
with a AS
(
SELECT
COUNT(order_id) AS Orders
FROM
Table_1
GROUP BY
Order_Id
)
SELECT
Orders,
COUNT(*) AS line
FROM
a
GROUP BY Orders
Basically, it just count how many times the order_id are repeated:
SELECT order_id, count(order_id) FROM data GROUP BY order_id
I currently have a SQL query that produces a table with around 10M rows. I would like to append this table with another column that has the same entry for all 10M rows.
As an example consider the following toy query
SELECT PRODUCT_ID, ORDER_QUANTITY
FROM PRODUCT_TABLE
GROUP BY SALES_DAY
And say that is produces the following table
PRODUCT_ID ORDER_QUANTITY`
1 10
2 12
3 14
How can I change this query so that it produces the following table, where every entry in USER_VALUE is 999.
PRODUCT_ID ORDER_QUANTITY USER_VALUE
1 10 999
2 12 999
3 14 999
I realize that there may be several answers here... but I suppose that it would help to know the method that would be produce the table with the smallest file size (I assume this would require specifying the type of data beforehand).
Like this:
SELECT PRODUCT_ID, ORDER_QUANTITY, 999 as USER_VALUE
FROM PRODUCT_TABLE
GROUP BY SALES_DAY
You can pass it in the SELECT, for example:
SELECT PRODUCT_ID, ORDER_QUANTITY, 999 AS USER_VALUE
FROM PRODUCT_TABLE
GROUP BY SALES_DAY
you can use
SELECT PRODUCT_ID, ORDER_QUANTITY, user_value=999
FROM PRODUCT_TABLE
GROUP BY SALES_DAY