SQL count occurrences of a value - sql

I am trying to count the occurrences of a value in SQL
id | my_id | field_number | field_id | value
------------------------------------------------------------
1 | 101 | 78 | 88 | apple
2 | 287 | 76 | 55 | orange
3 | 893 | 45 | 33 | orange
4 | 922 | 23 | 33 | grape
5 | 198 | 09 | 88 | raisin
6 | 082 | 55 | 88 | apple
If I use the following then it correctly tells me that there are 3 field_id's with the value of 88.....
$count = $wpdb->get_results("SELECT COUNT(*) as count FROM wp_db1 WHERE field_id=88");
But if I try and do this:
$count = $wpdb->get_results("SELECT COUNT(*) as count FROM wp_db1 WHERE value=apple");
Then it does not work. Can anyone help?

You missed the quotes around apple:
$count = $wpdb->get_results('SELECT COUNT(*) as count FROM wp_db1 WHERE value="apple"');

Related

How to reshape a table having multiple records for the same id into a table with one record per id without losing information?

Basically, I want to transform this(Initial) into this(Final). In other words, I want to
"squash" the initial table so that it will have only one record per id
"dilate" the initial table so that I won't lose any information: create a different column for every possible combination of source and column from the initial table (create c1_A, c1_B, ...).
I can work with the initial table as a csv in Python (maybe Pandas) and manually hardcode the mapping between the Initial and the Final table. However, I don't find this solution elegant at all and I'm much more interested in a sql / sas solution. Is there any way of doing that?
Edit: I what to change
+----+--------+------+-----+------+
| ID | source | c1 | c2 | c3 |
+----+--------+------+-----+------+
| 1 | A | 432 | 56 | 1 |
| 1 | B | 53 | 3 | 73 |
| 1 | C | 7 | 342 | 83 |
| 1 | D | 543 | 43 | 73 |
| 2 | A | 8 | 882 | 39 |
| 2 | B | 5 | 54 | 46 |
| 2 | C | 8 | 3 | 2226 |
| 2 | D | 87 | 2 | 45 |
| 3 | A | 93 | 143 | 45 |
| 3 | B | 1023 | 72 | 8 |
| 3 | C | 3 | 3 | 704 |
| 4 | A | 2 | 5 | 0 |
| 4 | B | 78 | 888 | 2 |
| 4 | C | 87 | 23 | 34 |
| 4 | D | 112 | 7 | 712 |
+----+--------+------+-----+------+
into
+----+------+------+------+------+------+------+------+------+------+------+------+------+
| ID | c1_A | c1_B | c1_C | c1_D | c2_A | c2_B | c2_C | c2_D | c3_A | c3_B | c3_C | c3_D |
+----+------+------+------+------+------+------+------+------+------+------+------+------+
| 1 | 432 | 53 | 7 | 543 | 56 | 3 | 342 | 43 | 1 | 73 | 83 | 73 |
| 2 | 8 | 5 | 8 | 87 | 882 | 54 | 3 | 2 | 39 | 46 | 2226 | 45 |
| 3 | 93 | 1023 | 3 | | 143 | 72 | 3 | | 45 | 8 | 704 | |
| 4 | 2 | 78 | 87 | 112 | 5 | 888 | 23 | 7 | 0 | 2 | 34 | 712 |
+----+------+------+------+------+------+------+------+------+------+------+------+------+
Abandon hope ... ?
data want;
input
ID source $ c1 c2 c3;datalines;
1 A 432 56 1
1 B 53 3 73
1 C 7 342 83
1 D 543 43 73
2 A 8 882 39
2 B 5 54 46
2 C 8 3 2226
2 D 87 2 45
3 A 93 143 45
3 B 1023 72 8
3 C 3 3 704
4 A 2 5 0
4 B 78 888 2
4 C 87 23 34
4 D 112 7 712
;
* one to grow you oh data;
proc transpose data=want out=stage1;
by id source;
var c1-c3;
run;
* and one to shrink;
proc transpose data=stage1 out=want(drop=_name_) delim=_;
by id;
id _name_ source;
run;

CTE - recursive query doing too much

I have the current table of data...
| LoanRollupID | NewLoanID | PreviousLoanID |
|--------------|-----------|----------------|
| 11 | 76 | 44 |
| 12 | 80 | 75 |
| 13 | 83 | 82 |
| 14 | 84 | 83 |
| 15 | 86 | 85 |
| 16 | 87 | 54 |
| 17 | 88 | 87 |
| 18 | 90 | 48 |
| 19 | 91 | 34 |
| 20 | 93 | 41 |
| 21 | 94 | 76 |
| 22 | 95 | 90 |
| 23 | 96 | 94 |
| 24 | 100 | 92 |
| 25 | 101 | 99 |
| 26 | 102 | 98 |
| 27 | 103 | 101 |
| 28 | 104 | 81 |
| 29 | 105 | 80 |
| 30 | 107 | 52 |
| 31 | 110 | 108 |
| 1029 | 1105 | 103 |
| 1030 | 1106 | 104 |
| 1031 | 1108 | 1106 |
| 1032 | 1109 | 73 |
I'm trying to jump in at NewLoanID 1108 and see how it has evolved from previous Loans. e.g 1108 came from 1106, which came from 104, which came from 81, etc.
When I run this query:
WITH OldLoans (PreviousLoanID, NewLoanID, start)
AS
(
---- Anchor member definition
SELECT l.NewLoanID, l.PreviousLoanID, 0 as start
FROM dscs_public.LoanRollup l
Where NewLoanID = 1108
UNION ALL
-- Recursive member definition
SELECT l.NewLoanID, l.PreviousLoanID, start + 1
FROM dscs_public.LoanRollup l
INNER JOIN OldLoans AS o
ON o.NewLoanID = l.PreviousLoanID
)
---- Statement that executes the CTE
SELECT PreviousLoanID, NewLoanID, start
FROM OldLoans
It fails with this error:
The statement terminated. The maximum recursion 100 has been exhausted
before statement completion.
Can anyone spot my mistake please?
Thanks.
The aliases in the CTE definition are in the wrong order:
-- Instead of (PreviousLoanID, NewLoanID, start)
WITH OldLoans (NewLoanID, PreviousLoanID, start)
AS
(
---- Anchor member definition
SELECT l.NewLoanID, l.PreviousLoanID, 0 as start
FROM mytable l --LoanRollup l
Where NewLoanID = 1108
UNION ALL
-- Recursive member definition
SELECT l.NewLoanID, l.PreviousLoanID, start + 1
FROM mytable l --dscs_public.LoanRollup l
INNER JOIN OldLoans AS o
-- Instead of o.NewLoanID = l.PreviousLoanID
ON l.NewLoanID = o.PreviousLoanID
)
---- Statement that executes the CTE
SELECT PreviousLoanID, NewLoanID, start
FROM OldLoans
The same thing holds for the ON clause in the recursive member definition.

delete duplicate rows from my table

i need to delete all duplicate rows in my table - but leave only one row
MyTbl
====
Code | ID | Place | Qty | User
========================================
1 | 22 | 44 | 34 | 333
2 | 22 | 44 | 34 | 333
3 | 22 | 55 | 34 | 333
4 | 22 | 44 | 34 | 666
5 | 33 | 77 | 12 | 999
6 | 44 | 11 | 87 | 333
7 | 33 | 77 | 12 | 999
i need to see this:
Code | ID | Place | Qty | User
=======================================
1 | 22 | 44 | 34 | 333
3 | 22 | 55 | 34 | 333
4 | 22 | 44 | 34 | 666
5 | 33 | 77 | 12 | 999
6 | 44 | 11 | 87 | 333
In most databases, the fastest way to do this is:
select distinct t.*
into saved
from mytbl;
delete from mytbl;
insert into mytbl
select *
from saved;
The above syntax should work in Access. Other databases would use truncate table instead of delete.
Try this,
WITH CTEMyTbl (A,duplicateRecCount)
AS
(
SELECT id,ROW_NUMBER() OVER(PARTITION by id,place,qty,us ORDER BY id)
AS duplicateRecCount
FROM MyTbl
)
DELETE FROM CTEMyTbl
WHERE duplicateRecCount > 1

Selecting records from Foreign Key table where multiple items match the condition

I am getting data from a third party in form of below tables in MS Access 2000 file format
Papers and
PaperTags
Below is the sample data from these tables.
Papers table and sample data
+----+----------+
| ID | PaperID |
+----+----------+
| 1 | 658 |
| 2 | 659 |
| 3 | 660 |
| 4 | 661 |
| 5 | 662 |
| 6 | 663 |
| 7 | 664 |
+----+----------+
PaperTags table and sample data
+----+----------+----------------------------------------+
| ID | PaperID | TagID |
+----+----------+----------------------------------------+
| 1 | 663 | 3 |
| 2 | 663 | 15 --Y |
| 3 | 663 | 17 |
| 4 | 663 | 18 --Y |
| 5 | 664 | 14 |
| 62 | 658 | 9 |
| 63 | 658 | 14 |
| 64 | 658 | 17 |
| 65 | 659 | 15 --Y |
| 66 | 659 | 17 |
| 67 | 659 | 18 --Y |
| 68 | 660 | 17 |
| 69 | 660 | 18 --N as it has only 18 and not 15 |
| 70 | 661 | 10 |
| 71 | 661 | 17 |
| 72 | 661 | 18 --N as it has only 18 and not 15 |
| 73 | 662 | 18 --N as it has only 18 and not 15 |
| 74 | 662 | 14 |
| 75 | 662 | 17 |
| 76 | 662 | 18 --N as it has only 18 and not 15 |
+----+----------+----------------------------------------+
Now my end user will pass one or more TagIDs for example 15 and 18 my goal is to find all the PaperIDs which have all of these TagIDs. In these example I need to return 663 and 659
I have tried below query but if there is any glitch in data then it doesn't work. For example PaperID 662 appears twice in the table with the same TagID so count(PaperID) = 2 turns out to be true and it will end up in my result.
select Count(PaperID), PaperID from PaperTags
group by TagID, PaperID
having TagID = 15 or TagID = 18
and count(PaperID) = 2
The other query that I tried is
select * from Papers
where Papers.PaperID
in
(
select PaperTags.PaperID from PaperTags
where (PaperTags.Tagid = 15 or PaperTags.Tagid = 18)
and PaperTags.PaperID = Papers.PaperID
)
I have gone thru below article but as I am using MSAccess I can't use this approach.
Select records from a table where all other records with same foreign key have a certain value
I think there has to be better way to filter. Any help is much appreciated.
Something like this:
SELECT G.ContentID
FROM (
SELECT PT.ContentID, PT.TagID
FROM PaperTags AS PT
WHERE PT.TagID IN (15, 18)
GROUP BY PT.ContentID, PT.TagID
) AS G
GROUP BY G.ContentId
HAVING Count(*) = 2

Sorting a group in datatable based on result in rows

I am trying to do a group sorting on Datatables. As of now I am having data like:
+-------+-----+--------+
| rowno | mno | result |
+-------+-----+--------+
| 1 | 80 | 20 |
| 1 | 81 | 10 |
| 1 | 82 | 30 |
| 2 | 80 | 40 |
| 2 | 81 | 50 |
| 2 | 82 | 60 |
| 3 | 80 | 70 |
| 3 | 81 | 60 |
| 3 | 82 | 50 |
+-------+-----+--------+
As per the requirement , i will be selecting a particular mno, lets say 81 and then depending on the result for 81 i.e. 10, 50 and 60, I would like to sort entire group in descending order. Which means the result would be something like:
+-------+-----+--------+
| rowno | mno | result |
+-------+-----+--------+
| 3 | 80 | 70 |
| 3 | 81 | 60 |
| 3 | 82 | 50 |
| 2 | 80 | 40 |
| 2 | 81 | 50 |
| 2 | 82 | 60 |
| 1 | 80 | 20 |
| 1 | 81 | 10 |
| 1 | 82 | 30 |
+-------+-----+--------+
I am having the entire set as Datatable and am thinking of applying Linq to solve this one. Or if a SQL Query could be suggested that would also be fine.
Try this
SELECT rowno,mno,result from your_table
order by rowno desc
With LINQ to DataSet (dt is your DataTable):
var sorted = dt.AsEnumerable()
.OrderByDescending(r => r.Field<int>("rowno"))
.CopyToDataTable();
Without LINQ:
var view = dt.DefaultView;
view.Sort = "rowno DESC";
var sorted = view.ToTable();