SQL: How to select and sum up columns in this query? - sql

I have been looking but not finding my precise case so I try asking here.
There is a query (which I unfortunately may not disclose) that has this structure:
WITH MAINRESULT AS
(
SELECT ... FROM ... WHERE...GROUP BY...
)
SELECT Name, SUM(MAINRESULT.Amount1 * AnotherAmount) AS MySum FROM MAINRESULT
WHERE .....
GROUP BY Name, AnotherAmount
ORDER BY Name
Now, I get something like this:
**Name** **MySum**
A 5
A 5
B 1
C 2
But I want to have this result SUM-med up so that I get:
**Name** **MySum**
A 10
B 1
C 2
How do I do this by modifying the query struture that I have?
Tried adding a "SELECT FROM" around both the WITH-query parn and the Second SELECT below it but it says I have syntax errors then.
UPDATE:
I had been staring for too long at that Query I missed that the AnotherAmount should not be included in the GROUP BY part. Thanks everyone for pointing it out so quickly!

It looks like you need to remove GROUP BY Name, AnotherAmount and left only GROUP BY Name in your query. Otherwise your results being groupped not only by Name but also by some AnotherAmount field - this may cause unexpected result you're getting.

Related

Not exists query is not returning expected info

I have a query, and for some reason I'm not getting the orderid 10 info as expected. The results give no lines. The query without the not exists part gives the below info.
The table looks like this:
orderid id number fulfilledproduct
2 BundleSpec 1 ID
2 TemplateSpec 1 IDSheet
2 TemplateSpec 1 IDCertificate
10 BundleSpec 1 ID
10 TemplateSpec 1 IDSheet
For some reason my query returns 0 lines when I try to get the orderid without the IDCertificate.
It's probably something I need to fix for the not exists part since I don't do that very often. Any ideas?
select (orderid),(id),(number),(fulfilledproduct)
from [Product]
where
id in ('BundleSpec','TemplateSpec')
and not exists
(
select (orderid)
from [Product]
where
id in ('BundleSpec','TemplateSpec')
and fulfilledproduct = 'IDCertificate'
)
I thought I was following an example correctly. Should I use except instead like except does?
Expected Output:
orderid id number fulfilledproduct
10 BundleSpec 1 ID
10 TemplateSpec 1 IDSheet
Note that this is using a dlx sql command on a device at the command line, and my example had the () and [] for the table info in the query so I'm using that too. It should give output the same way microsoft sql works in sql server as I am told. I have formatted the query for easy viewing and removed the command line syntax.
This is because your not-exists clause has nothing tying it to the main query. Your not-exists query always returns a row, so therefore the main query returns nothing.
You need to tell it something like this:
select (orderid),(id),(number),(fulfilledproduct)
from [Product] p
where
id in ('BundleSpec','TemplateSpec')
and not exists
(
select 1
from [Product] p2
where
p2.orderid = p.orderid
and p2.fulfilledproduct = 'IDCertificate'
)

SQL order by clause customized

I want to run a query that fetches me all the names that have for say "ana" in it but i want the result like this
Anna
Brianna
not like
Brianna
Anna
which means the name starting with "an" should come first and then anything containing "an" in them
My SQL query is like this but this dpes not give me the desired results. I checked some other stuff but not quite sure how to use and does not give the desired results.
SELECT *
FROM TABLE_NAME
WHERE Name LIKE 'ana%'
AND Name LIKE '%ana%'
You need to select the records only once and then order them and according to your requirements i understand that you need to order something like this by using ORDER BY CASE
SELECT *
FROM TABLE_NAME
WHERE Name LIKE '%ana%'
ORDER BY CASE
WHEN Name LIKE 'an%' THEN 1
WHEN Name LIKE '%an%' THEN 2
ELSE 3
END

SQL list multiple Duplicates

running a SQL query in access that is giving me matches where A = record 1, and B also = record 1 , C= record 2 and D E and F also = record 2.
I want my results to display (only max Value)
B =record 1
F= record 2. ( this is a matching query)
basically i want to eliminate duplicates and select "distinct" does not seem to be working for me.
SELECT
FEED_2.ID AS FEED_2_ID,
FEED_3.field_ID,
FEED_3.ID AS FEED_3_ID
FROM FEED_2 INNER JOIN FEED_3 ON FEED_2.[field_ID] = FEED_3.[field_ID]
order by FEED_3.ID
im getting results where feed 2 ID #1,3, and 5 all equal feed 3 - ID #1
i only want feed 2, #5 = feed 3 #1. no Dupes
sorry - hope that helps
It's a shot in the dark but, is something like this you are looking for?
SELECT max(Column_With_ABCDEF), Column_With_record from TABLE_NAME GROUP BY Column_With_record;
If this is not what you are asking for, please do edit your question with your table schema and/or the query you are using so we can help.
---------------- EDIT ----------------
Ok so you can try this:
Select max(FEED_2_ID), field_ID , FEED_3_ID
from (
SELECT FEED_2.ID AS FEED_2_ID, FEED_3.field_ID As field_ID, FEED_3.ID AS FEED_3_ID
FROM FEED_2 INNER JOIN FEED_3
ON FEED_2.[field_ID] = FEED_3.[field_ID]
)
GROUP BY FEED_3_ID, field_ID
ORDER BY FEED_3_ID
The main select is going to group the result from the subquery, that way you should not get duplicated values.
Hope this help

How do I preserve the order of a SQL query using the IN command

SELECT * FROM tblItems
WHERE itemId IN (9,1,4)
Returns in the order that SQL finds them in (which happens to be 1, 4, 9) however, I want them returned in the order that I specified in the array.
I know I could reorder them after in my native language (obj c), but is there a neat way to do this in SQL?
Somthing like this would be great:
ORDER BY itemId (9,1,4) -- <-- this dosn't work :)
Probably the best way to do this is create a table of item IDs, which also includes a rank order. Then you can join and sort by the rank order.
Create a table like this:
itemID rank
9 1
1 2
4 3
Then your query would look like this:
select tblItems.* from tblItems
inner join items_to_get on
items_to_get.itemID = tblItems.itemID
order by rank
Use a CASE expression to map the ID values to an increasing sequence:
... ORDER BY CASE itemId
WHEN 9 THEN 1
WHEN 1 THEN 2
ELSE 3
END
I had the same task once in a mysql environment.
I ended up using
ORDER BY FIND_IN_SET(itemID, '9,1,4')
this is working for me since then. I hope it also works for sqlite
You can add a case construct to your select clause.
select case when itemid = 9 then 1
when itemid = 1 then 2 else 3 end sortfield
etc
order by sortfield
You could create a procedure to order the data in SQL, but that would be much more complicated than its native language counterpart.
There's no "neat way" to resort the data like that in SQL -- the WHERE clause of a SELECT simply says "if these criteria are matched, include the row"; it's not (and it cannot be) an ordering criterion.

How to group by a column

Hi I know how to use the group by clause for sql. I am not sure how to explain this so Ill draw some charts. Here is my original data:
Name Location
----------------------
user1 1
user1 9
user1 3
user2 1
user2 10
user3 97
Here is the output I need
Name Location
----------------------
user1 1
9
3
user2 1
10
user3 97
Is this even possible?
The normal method for this is to handle it in the presentation layer, not the database layer.
Reasons:
The Name field is a property of that data row
If you leave the Name out, how do you know what Location goes with which name?
You are implicitly relying on the order of the data, which in SQL is a very bad practice (since there is no inherent ordering to the returned data)
Any solution will need to involve a cursor or a loop, which is not what SQL is optimized for - it likes working in SETS not on individual rows
Hope this helps
SELECT A.FINAL_NAME, A.LOCATION
FROM (SELECT DISTINCT DECODE((LAG(YT.NAME, 1) OVER(ORDER BY YT.NAME)),
YT.NAME,
NULL,
YT.NAME) AS FINAL_NAME,
YT.NAME,
YT.LOCATION
FROM YOUR_TABLE_7 YT) A
As Jirka correctly pointed out, I was using the Outer select, distinct and raw Name unnecessarily. My mistake was that as I used DISTINCT , I got the resulted sorted like
1 1
2 user2 1
3 user3 97
4 user1 1
5 3
6 9
7 10
I wanted to avoid output like this.
Hence I added the raw id and outer select
However , removing the DISTINCT solves the problem.
Hence only this much is enough
SELECT DECODE((LAG(YT.NAME, 1) OVER(ORDER BY YT.NAME)),
YT.NAME,
NULL,
YT.NAME) AS FINAL_NAME,
YT.LOCATION
FROM SO_BUFFER_TABLE_7 YT
Thanks Jirka
If you're using straight SQL*Plus to make your report (don't laugh, you can do some pretty cool stuff with it), you can do this with the BREAK command:
SQL> break on name
SQL> WITH q AS (
SELECT 'user1' NAME, 1 LOCATION FROM dual
UNION ALL
SELECT 'user1', 9 FROM dual
UNION ALL
SELECT 'user1', 3 FROM dual
UNION ALL
SELECT 'user2', 1 FROM dual
UNION ALL
SELECT 'user2', 10 FROM dual
UNION ALL
SELECT 'user3', 97 FROM dual
)
SELECT NAME,LOCATION
FROM q
ORDER BY name;
NAME LOCATION
----- ----------
user1 1
9
3
user2 1
10
user3 97
6 rows selected.
SQL>
I cannot but agree with the other commenters that this kind of problem does not look like it should ever be solved using SQL, but let us face it anyway.
SELECT
CASE main.name WHERE preceding_id IS NULL THEN main.name ELSE null END,
main.location
FROM mytable main LEFT JOIN mytable preceding
ON main.name = preceding.name AND MIN(preceding.id) < main.id
GROUP BY main.id, main.name, main.location, preceding.name
ORDER BY main.id
The GROUP BY clause is not responsible for the grouping job, at least not directly. In the first approximation, an outer join to the same table (LEFT JOIN below) can be used to determine on which row a particular value occurs for the first time. This is what we are after. This assumes that there are some unique id values that make it possible to arbitrarily order all the records. (The ORDER BY clause does NOT do this; it orders the output, not the input of the whole computation, but it is still necessary to make sure that the output is presented correctly, because the remaining SQL does not imply any particular order of processing.)
As you can see, there is still a GROUP BY clause in the SQL, but with a perhaps unexpected purpose. Its job is to "undo" a side effect of the LEFT JOIN, which is duplication of all main records that have many "preceding" ( = successfully joined) records.
This is quite normal with GROUP BY. The typical effect of a GROUP BY clause is a reduction of the number of records; and impossibility to query or test columns NOT listed in the GROUP BY clause, except through aggregate functions like COUNT, MIN, MAX, or SUM. This is because these columns really represent "groups of values" due to the GROUP BY, not just specific values.
If you are using SQL*Plus, use the BREAK function. In this case, break on NAME.
If you are using another reporting tool, you may be able to compare the "name" field to the previous record and suppress printing when they are equal.
If you use GROUP BY, output rows are sorted according to the GROUP BY columns as if you had an ORDER BY for the same columns. To avoid the overhead of sorting that GROUP BY produces, add ORDER BY NULL:
SELECT a, COUNT(b) FROM test_table GROUP BY a ORDER BY NULL;
Relying on implicit GROUP BY sorting in MySQL 5.6 is deprecated. To achieve a specific sort order of grouped results, it is preferable to use an explicit ORDER BY clause. GROUP BY sorting is a MySQL extension that may change in a future release; for example, to make it possible for the optimizer to order groupings in whatever manner it deems most efficient and to avoid the sorting overhead.
For full information - http://academy.comingweek.com/sql-groupby-clause/
SQL GROUP BY STATEMENT
SQL GROUP BY clause is used in collaboration with the SELECT statement to arrange identical data into groups.
Syntax:
1. SELECT column_nm, aggregate_function(column_nm) FROM table_nm WHERE column_nm operator value GROUP BY column_nm;
Example :
To understand the GROUP BY clauserefer the sample database.Below table showing fields from “order” table:
1. |EMPORD_ID|employee1ID|customerID|shippers_ID|
Below table showing fields from “shipper” table:
1. | shippers_ID| shippers_Name |
Below table showing fields from “table_emp1” table:
1. | employee1ID| first1_nm | last1_nm |
Example :
To find the number of orders sent by each shipper.
1. SELECT shipper.shippers_Name, COUNT (orders.EMPORD_ID) AS No_of_orders FROM orders LEFT JOIN shipper ON orders.shippers_ID = shipper.shippers_ID GROUP BY shippers_Name;
1. | shippers_Name | No_of_orders |
Example :
To use GROUP BY statement on more than one column.
1. SELECT shipper.shippers_Name, table_emp1.last1_nm, COUNT (orders.EMPORD_ID) AS No_of_orders FROM ((orders INNER JOIN shipper ON orders.shippers_ID=shipper.shippers_ID) INNER JOIN table_emp1 ON orders.employee1ID = table_emp1.employee1ID)
2. GROUP BY shippers_Name,last1_nm;
| shippers_Name | last1_nm |No_of_orders |
for more clarification refer my link
http://academy.comingweek.com/sql-groupby-clause/