how to get rows with count of occurence (Frequency) in the table - sql

My Database Table is having this type of data
Table Name : Logs
ID ALBUMID GENREID
1 1005 5
1 1008 5
1 1006 4
1 1005 5
1 1007 5
1 1007 4
1 1008 5
1 1008 5
1 1005 5
1 1005 4
1 1005 5
and the result I am expecting is for get - Top 2 Album id with frequency count for GenreId 5 which have maximum frequency..
Result :
AlbumId Frequency
1005 4
1008 3
here is SQL Fiddle Link http://sqlfiddle.com/#!6/aaa9e/13

Please try:
select top 2 ALBUMID, COUNT(*) Frequency
from tbl
where GENREID=5
group by ALBUMID
order by 2 desc

Related

SQL query to select specific fields, process sum and count from two tables

i have these two tables
ORDERS
id order_id e_id e_name
1 1000 1001 Tom
2 1009 1001 Tom
3 1010 1001 Tom
4 1011 1002 Parker
5 1012 1002 Parker
6 1013 1003 Rohan
Transactions
id order_id amount status
1 1000 100 success
2 1009 80 success
3 1010 100 failed
4 1011 50 success
6 1012 50 success
7 1013 100 failed
i would like to join two tables, select fields, process sum count and filter like this
e_id e_name amount_sum total_counts total_success_amount success_count
1001 Tom 280 3 180 2
1002 Parker 100 2 100 2
1003 Rohan 100 1 0 0
this is what i tried
use card;
SELECT COUNT(orders.order_id) as `total_counts`,
COUNT(CASE WHEN transactions.status = 'success' THEN 1 END) as `success_count`,
SUM(0 + transactions.amount) as `amount_sum`, orders.e_id,
orders.e_name
FROM orders
LEFT JOIN transactions
ON transactions.order_id=orders.order_id
GROUP BY (orders.e_id), (orders.order_id),
(orders.e_name), (transactions.amount), (transactions.status);
i tried many queries also not able to achieve it. Suggest me query to get my operation.

How To Arrange Table Data in Parent_Id And Child_Id Wise Via Sql-Server Query

How To Arrange Table Data in Parent_Id And Child_Id Wise Via Sql-Server Query?
My Query
select CLevel_Id,Category_Name,Parent_Id,Child_Id,Level_Id from Category_Level
order by Parent_Id asc
Current Output
CLevel_Id Category_Name Parent_Id Child_Id Level_Id
12 Jewelry 1 0 1
14 Rings 2 1 2
15 Men-Rings 3 2 3
17 Women-Rings 4 2 3
18 Earrings 5 1 2
20 Women-Earings 6 5 3
1013 Metal-Fashion 7 3 4
1015 Diamond-Fashion 8 4 4
1016 Semi-Set 9 6 4
Expected Output
CLevel_Id Category_Name Parent_Id Child_Id Level_Id
12 Jewelry 1 0 1
14 Rings 2 1 2
15 Men-Rings 3 2 3
1013 Metal-Fashion 7 3 4
17 Women-Rings 4 2 3
1015 Diamond-Fashion 8 4 4
18 Earrings 5 1 2
20 Women-Earings 6 5 3
1016 Semi-Set 9 6 4
please help me
use a Recursive CTE.
Assuming you have max 9 per level. Using single digit as the seq level. If you have more than 9, you will need to use 2 digits like 01, 02 etc
; with
rcte as
(
-- Anchor member, seq = 1
select *, seq = convert(varchar(100), '1')
from Category_Level
where Child_Id = 0
union all
-- recursive member, concatenate to the seq
select c.*, seq = convert(varchar(100),
r.seq
+ convert(varchar(10), row_number() over (partition by r.seq
order by c.Child_Id)))
from Category_Level c
inner join rcte r on c.Child_Id = r.Parent_Id
)
select *
from rcte
order by seq
/* RESULT
CLevel_Id Category_Name Parent_Id Child_Id Level_Id seq
----------- -------------------- ----------- ----------- ----------- -------
12 Jewelry 1 0 1 1
14 Rings 2 1 2 11
15 Men-Rings 3 2 3 111
1013 Metal-Fashion 7 3 4 1111
17 Women-Rings 4 2 3 112
1015 Diamond-Fashion 8 4 4 1121
18 Earrings 5 1 2 12
20 Women-Earings 6 5 3 121
1016 Semi-Set 9 6 4 1211
(9 rows affected)
*/

Selecting the last instance of the record but returning the first instance of it

I have table that consist logs of calls.
callid calling_pty dialed_num disposition dispvdn segment ucid
3862073 25555366 1001 1 1001 1 10000080561437527378
3862073 291113 1015 2 1015 2 10000080621437527416
3862074 635444419 1001 3 1001 1 10000081311437527892
3862075 25555596 1001 1 1001 1 10000081211437527803
3862075 26669 1014 3 1014 2 10000081231437527820
3862076 23044442 1009 2 1009 1 10000080961437527654
3862079 632444419 1001 1 1001 1 10000081361437527904
3862089 0111808 1001 1 1001 1 10000081671437528068
3862091 02366674 1001 1 1001 1 10000081011437527679
3862091 26666 1015 2 1015 2 10000081091437527712
3862097 63255529 1001 1 1001 1 10000081721437528139
3862097 29111 1014 3 1014 2 10000081771437528168
Given the sample data, I need to select the records with disposition = 3, but I need to check first if it has an earlier segment [disposition is the status of the call, 3 for abandon and segment is the number of call instances if it is transferred or not in one transaction]. and return the calling_pty(caller number) of the first instance, hence if there is none, it will return the number of that record. And it can be identifiend with the help of the callid
So with the given sample,
3862075 25555596 1001 1 1001 1 10000081211437527803
3862075 26669 1014 3 1014 2 10000081231437527820
it will return to me "25555596", they have the same callid but different calling party which would mean the call was transferred and then it was abandoned.
Therefore: the resulting record should be the "25555596" record.
*This would apply to all records of the same conditions and it will be populated as a list
3862074 635444419 1001 3 1001 1 10000081311437527892
3862075 25555596 1001 1 1001 1 10000081211437527803
3862097 63255529 1001 1 1001 1 10000081721437528139
*this will be the end result for the sample data
I did a nested select but im on the dead end of how I will check for the first instance. is there a sql function to achieve this?
I used two correlated sub-queries:
SELECT callid,
(SELECT calling_pty
FROM Log l
WHERE Log.callid = l.callid AND
segment = (SELECT MIN(segment)
FROM Log l2
WHERE l.callid = l2.callid)
)[calling_pty],
dialed_num, disposition, dispvdn, segment, ucid
FROM Log
WHERE disposition = 3
SQL Fiddle Demo

How to find all (group-based) rows containing MIN/MAX values for a particular column in SQL Server?

I have temporary table (#TempPackages) which looks like this:
EntryId (PK) PackageId SubProductID SubProductSequence
1 1111 17 3
2 1111 28 4
3 1111 33 1
4 1111 67 5
5 1111 122 2
6 2222 18 4
7 2222 29 5
8 2222 33 9
9 2222 103 7
10 2222 99 11
11 3333 256 5
12 3333 333 6
13 3333 789 3
14 3333 1023 2
15 3333 9845 1
I need a query which will give me the rows with the minimum/maximum SubProductSequence value for each unique PackageId. For the table above, the query would return this:
EntryId (PK) PackageId SubProductID SubProductSequence
3 1111 33 1
4 1111 67 5
6 2222 18 4
10 2222 99 11
12 3333 333 6
15 3333 9845 1
The EntryId column was something that I added while trying to solve this, as it gives me a unique column to join the same table on to (to ensure I still only end up with 15 rows in my joined table).
I tried this - just to get the MIN():
SELECT
*
FROM
#TempPackages p1
INNER JOIN
#TempPackages p2 ON p1.EntryId = p2.EntryId
AND p1.SubProductSequence = (
SELECT
MIN(SubProductSequence)
FROM
#DeparturesToUpdate)
Obviously this is wrong, because the INNER JOIN is superfluous and the SELECT MIN() clause is wrong as it selects the rows with the minimum overall sequence numbers, not the minimum sequence numbers per package.
Any suggestions about the best way to do this?
One way is to use the ROW_NUMBER() function:
SELECT
EntryId
, PackageId
, SubProductID
, SubProductSequence
FROM
( SELECT
EntryId
, PackageId
, SubProductID
, SubProductSequence
, ROW_NUMBER() OVER (PARTITION BY PackageId
ORDER BY SubProductSequence ASC)
AS rna
, ROW_NUMBER() OVER (PARTITION BY PackageId
ORDER BY SubProductSequence DESC)
AS rnd
FROM
#TempPackages
) AS tmp
WHERE
rna = 1
OR rnd = 1 ;
ROW_NUMBER() is a ranking function that is used with OVER clause. What it basically does in this case, is it groups the rows with same PackageId (that is done with the PARTITION BY PackageId), then orders them by SubProductSequence (ascending or descending) and assigns a row_number, starting from 1 for each packageId.
So, the subquery would return this, if it was run alone:
EntryId (PK) PackageId SubProductID SubProductSequence rna rnd
3 1111 33 1 1 5
5 1111 122 2 2 4
1 1111 17 3 3 3
2 1111 28 4 4 2
4 1111 67 5 5 1
6 2222 18 4 1 5
7 2222 29 5 2 4
9 2222 103 7 3 3
8 2222 33 9 4 2
10 2222 99 11 5 1
15 3333 9845 1 1 5
14 3333 1023 2 2 4
13 3333 789 3 3 3
11 3333 256 5 4 2
12 3333 333 6 5 1
The WHERE condition added in the external query is obvious afterwards.
Improving on Bohemian's idea -
;WITH MinMax AS
(SELECT PackageId ,
MIN(SubProductSequence) [Min],
MAX(SubProductSequence) [Max]
FROM #TempPackages
GROUP BY PackageId )
SELECT EntryId, SubProductSequence, TP.PackageId, SubProductID FROM #TempPkges TP
INNER JOIN MinMax MM ON TP.PackageId = MM.PackageId
AND (SubProductSequence = MM.[Min] OR SubProductSequence = MM.[Max])
And then, you can add your own ORDER BY
WITH t1 AS
(SELECT PackageId,MIN(SubProductSequence) minm,MAX(SubProductSequence) maxm
FROM ##TempPackages
GROUPBY PackageId
)
SELECT pk.EntryId, pk.PackageId,pk.SubProductID, pk.SubProductSequence
FROM ##TempPackages pk INNER JOIN t1
ON pk.PackageId = t1.PackageId
WHERE pk.SubProductSequence = t1.minm OR
pk.SubProductSequence = t1.maxm

Joining two tables in Oracle sql

I have 2 tables. One of the tables have 7 values and the other table has 5 values. These tables have their primary keys in common. I want to join both tables this way:
If I have a Table
English French
-------------------- --------------------
one Un
two Deux
three Trois
four Quatre
four Quattro
five Cinq
five Cinco
And another one:
English French
-------------------- --------------------
one aaaaa
two bbbbb
three ccccc
four
five
I want to have a table like this:
English French
-------------------- --------------------
one Un
one aaaaa
two Deux
two bbbb
three Trois
three ccccc
four Quatre
four Quattro
four --------
five Cinq
five Cinco
five ----------
I tried using join but it does a linear combination of the values four and five. How can I go about doing this? Thanks.
Edit: SQL query:
SELECT l.date_location, l.duree, r.km_restitution, r.km_parcouru
FROM locations l, restitutions r
UNION
SELECT l.num_client, l.date_location, l.duree, r.km_restitution, r.km_parcouru
FROM locations l, restitutions r
id_agence num_immatriculation num_client km_restitution km_parcouru state date_restitution
1 406BON69 1002 30000 1000 BON 29-MAY-10
3 785CIM13 1001 56580 80 BON 09-AUG-08
5 800BBB75 1000 2020 20 BON 24-APR-11
4 307VXN78 1000 20040 40 BON 28-JAN-11
2 290UTT92 1004 30030 30 BON 01-AUG-10
5 777SET13 1005 4030 30 BON 26-APR-11
2 179CLV92 1004 15015 15 BON 03-FEB-11
5 400AAA75 1003 1020 20 BON 18-SEP-11
5 666NEF69 1004 3040 40 BON 15-APR-11
2 111AAA75 1001 20020 20 BON 21-DEC-09
1 333CCC78 1001 43250 40 BON 27-DEC-09
2 260CDE95 1003 79000 430 BON 10-SEP-09
4 307VXN78 1003 20090 90 BON 11-FEB-11
1 123ABC78 1003 10010 10 BON 04-OCT-10
1 222BBB77 1001 9050 50 BON 23-DEC-09
Locations
id_agence num_immatricul num_client duree date_location
2 406BON69 1002 20 10-MAY-10
3 785CIM13 1001 3 07-AUG-08
5 800BBB75 1000 7 18-APR-11
4 307VXN78 1000 5 24-JAN-11
1 290UTT92 1004 1 31-JUL-10
5 777SET13 1005 4 23-APR-11
1 179CLV92 1004 5 30-JAN-11
5 400AAA75 1003 2 17-SEP-11
2 123ABC78 1003 4 01-OCT-10
5 666NEF69 1004 5 11-APR-11
1 111AAA75 1001 2 20-DEC-09
1 222BBB77 1001 2 22-DEC-09
1 333CCC78 1001 3 25-DEC-09
1 260CDE95 1003 10 01-SEP-09
4 307VXN78 1003 13 30-JAN-11
2 123ABC78 1003 8 20-NOV-11
2 406BON69 1002 10 20-NOV-11
Desired Result
id_agence num_immatricul num_client duree date_location date_restitution
2 406BON69 1002 20 10-MAY-10 date_restitution
3 785CIM13 1001 3 07-AUG-08 date_restitution
5 800BBB75 1000 7 18-APR-11 date_restitution
4 307VXN78 1000 5 24-JAN-11 date_restitution
1 290UTT92 1004 1 31-JUL-10 date_restitution
5 777SET13 1005 4 23-APR-11 date_restitution
1 179CLV92 1004 5 30-JAN-11 date_restitution
5 400AAA75 1003 2 17-SEP-11 date_restitution
2 123ABC78 1003 4 01-OCT-10 date_restitution
5 666NEF69 1004 5 11-APR-11 date_restitution
1 111AAA75 1001 2 20-DEC-09 date_restitution
1 222BBB77 1001 2 22-DEC-09 date_restitution
1 333CCC78 1001 3 25-DEC-09 date_restitution
1 260CDE95 1003 10 01-SEP-09 date_restitution
4 307VXN78 1003 13 30-JAN-11 date_restitution
2 123ABC78 1003 8 20-NOV-11 ----------------
2 406BON69 1002 10 20-NOV-11 ---------------
Apart from the column name, where i put date_restitution contains real dates.
You could use a UNION:
select English, French from Table1
UNION ALL
select English, French from Table2
or a full outer join
select distinct coalesce(T1.English, T2.English), coalesce(T1.French, T2.French)
from Table1 T1
full outer join Table2 T2 on T1.English = T2.English
EDIT:
Assuming you want restitutions.date_restitution to appear in place of date_location for restitution records -
SELECT l.num_client, l.date_location, l.duree, to_number(null) km_restitution, to_number(null) km_parcouru
FROM locations l
UNION ALL
SELECT r.num_client, r.date_restitution date_location, 0 duree, r.km_restitution, r.km_parcouru
FROM restitutions r
FURTHER EDIT (based on supplied results):
select l.id_agence,
l.num_immatricul,
l.num_client,
l.duree,
l.date_location,
decode(r.date_restitution, NULL,'----------------', 'date_restitution')
as date_restitution -- or just r.date_restitution
from location l
left outer join restitution r
on l.id_agence = r.id_agence and
l.num_immatricul = r.num_immatricul and
l.num_client = r.num_client and
l.date_location <= r.date_restitution
You actually need a union:
SELECT English, French FROM T1
UNION
SELECT English, French FROM T2
If you don't care about duplicates, you can use UNION ALL
Edit after OP's comment:
SELECT l.num_client, l.id_agence, l.num_immatricul
FROM locations l
UNION
SELECT r.num_client, r.id_agence, r.num_immatriculation
FROM restitutions r
The following should do it.
SELECT tab1.English, tab1.French
UNION
SELECT tab2.English, tab2.French
For other readers who might have the same problem. From the experience I had with this problem, it would be a good idea to join tables locations and restitutions since both of them have almost the same attributes and data. I finally decided in changing my database and creating a new table that contains both the attributes of location and restitution and setting some not availabe values to NULL. This would reduce a lot of joins between tables and queries would be easier to handle.