How to add a user defined column with a single value to a SQL query - sql

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

Related

Must I use inner join if I want to use MAX() value as a "where" condition?

My table is like this:
ProductID ProductName SupplierID CategoryID Unit Price
1 Chais 1 1 10 boxes x 20 bags 18
2 Chang 1 1 24 - 12 oz bottles 19
3 Aniseed Syrup 1 2 12 - 550 ml bottles 10
4 Chef Anton's
Cajun Seasoning 2 2 48 - 6 oz jars 21.35
5 Chef Anton's
Gumbo Mix 2 2 36 boxes 25
I copy it from https://www.w3schools.com/sql/sql_func_max.asp
I tried the simple version of MAX() function test, it works. But when I use the HighestPrice in the WHERE condtion as following:
SELECT
MAX(Price) AS HighestPrice,
SupplierID
FROM Products
GROUP BY SupplierID
WHERE HighestPrice>20;
The sytem report ERROR as:
Error: misuse of aggregate: MAX()
Does it mean I must use inner join to get what I want?
Following query should work:
SELECT SupplierID, MAX(Price) AS HighestPrice
FROM Products
GROUP BY SupplierID
HAVING MAX(Price) > 20;
following is the correct syntax of writing any SQL query:
SELECT column_name1,
SUM(column_name2)
FROM table_name
WHERE [CONDITION]
GROUP BY column_name1
HAVING (arithematic function condition);
Use having instead of where .
Where is always used before group by statement. It is way to filter the data which is already available with us whereas having is used after group by statement because it is applied on the data which we are in process of making.
SELECT MAX(Price) AS HighestPrice, SupplierID
FROM Products
Group By SupplierID
having MAX(Price) > 20;
Let me know in case of any queries.
Just for fun. If you specifically want to use where condition for highest price instead of having clause as given by G.arima with max function again. Do this:-
SELECT *
FROM
(
SELECT
MAX(Price) AS HighestPrice,
SupplierID
FROM Products
GROUP BY SupplierID
) a
WHERE HighestPrice>20;
Hope it helps :-)
By way of explanation of G.arima’s answer above:
When you use GROUP BY, you effectively create a new virtual table which contains only the GROUP BY fields as well as summaries.
There are two filter clauses, WHERE and HAVING, but they have a distinct role.
WHERE filters the original table. This gives you the formula FROM … WHERE …
HAVING filters the groups. This gives you the formula GROUP BY … HAVING …
What you ask is OK, but the clause is the wrong one. As G.arima says, you should use HAVING.

Select multiple rows from a table where field is the max date

I have a table called Product. I need to select all product records that have the MAX ManufatureDate.
Here is a sample of the table data:
Id ProductName ManufactureDate
1 Car 01-01-2015
2 Truck 05-01-2015
3 Computer 05-01-2015
4 Phone 02-01-2015
5 Chair 03-01-2015
This is what the result should be since the max date of all the records is 05-01-2015 and these 2 records have this max date:
Id ProductName ManufactureDate
2 Truck 05-01-2015
3 Computer 05-01-2015
The only way I can think of doing this is by first doing a query on the entire table to find out what the max date is and then store it in a variable #MaxManufatureDate. Then do a second query where ManufactureDate=#MaxManufactureDate. Something tells me there is a better way.
There are 1 million+ records in this table:
Here is the way I am currently doing it:
#MaxManufactureDate = select max(ManufactureDate) from Product
select * from Product where ManufactureDate = #MaxManufactureDate
If figure this is a lot better then doing a subselect in a where clause. Or is this the same exact thing as doing a subselect in a where clause? I am not sure if the query gets ran for each row regardless or if sqlserver stored the variable value in memory.
select * from product
where manufactureDate = (select max(manufactureDate) from product)
The inner select-statements selects the maximum date, the outer all products which have the date.
You can use a subQuery
SELECT *
FROM Product
WHERE ManufactureDate = (
SELECT ManufactureDate
FROM Product
ORDER BY ManufactureDate
LIMIT 1
);`
You may need to use ASC or DESC to collect the right order
Try this pattern:
SELECT Id, ProductName, ManufactureDate
FROM (
SELECT Id, ProductName, ManufactureDate, MAX(ManufactureDate)OVER() AS MaxManufactureDate
FROM Product P
) P
WHERE P.MaxManufactureDate = P.ManufactureDate
Essentially, use a window function to get the data you're looking for in the inline view, then use the where clause in the outer query to match them.

Update SQL Query to add rows from a single table but combine 1 columns values togethor

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

SQL Remove Duplicates, save lowest of certain column

I've been looking for an answer to this but couldn't find anything the same as this particular situation.
So I have a one table that I want to remove duplicates from.
__________________
| JobNumber-String |
| JobOp - Number |
------------------
So there are multiples of these two values, together they make the key for the row. I want keep all distinct job numbers with the lowest job op. How can I do this? I've tried a bunch of things, mainly trying the min function, but that only seems to work on the entire table not just the JobNumber sets. Thanks!
Original Table Values:
JobNumber Jobop
123 100
123 101
456 200
456 201
780 300
Code Ran:
DELETE FROM table
WHERE CONCAT(JobNumber,JobOp) NOT IN
(
SELECT CONCAT(JobNumber,MIN(JobOp))
FROM table
GROUP BY JobNumber
)
Ending Table Values:
JobNumber Jobop
123 100
456 200
780 300
With SQL Server 2008 or higher you can enhance the MIN function with an OVER clause specifying a PARTITION BY section.
Please have a look at https://msdn.microsoft.com/en-us/library/ms189461.aspx
You can simply select the values you want to keep:
select jobOp, min(number) from table group by jobOp
Then you can delete the records you don't want:
DELETE t FROM table t
left JOIN (select jobOp, min(number) as minnumber from table group by jobOp ) e
ON t.jobob = e.jobob and t.number = e.minnumber
Where e.jobob is null
I like to do this with window functions:
with todelete as (
select t.*, min(jobop) over (partition by numbers) as minjop
from table t
)
delete from todelete
where jobop > minjop;
It sounds like you are not using the correct GROUP BY clause when using the MIN function. This sql should give you the minimum JobOp value for each JobNumber:
SELECT JobNumber, MIN(JobOp) FROM test.so_test GROUP BY JobNumber;
Using this in a subquery, along with CONCAT (this is from MySQL, SQL Server might use different function) because both fields form your key, gives you this sql:
SELECT * FROM so_test WHERE CONCAT(JobNumber,JobOp)
NOT IN (SELECT CONCAT(JobNumber,MIN(JobOp)) FROM test.so_test GROUP BY JobNumber);

Using Alias with MySql

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 ...