mySQL count occurances of value on multiple fields. How? - mysql

I have a table with 5 fields. Each field can store a number from 1 - 59.
Similar to countif in Excel, how do I count the number of times a number from 1 - 59 shows up in all 5 fields?
Here's an example for the count of occurances for the number 1 in all five fields:
SELECT SUM(pick_1 = 1 OR pick_2 = 1 OR pick_3 = 1 OR pick_4 = 1 OR pick_5 = 1) AS total_count_1
FROM tbldraw
Hopefully I made sense.

There was an answer here that had a solution. I think this is just a variation.
Step1: Create a numbers table (1 field, called id, 59 records (values 1 -59))
Step2:
SELECT numbers_table.number as number
, COUNT(tbldraw.pk_record)
FROM numbers_table
LEFT JOIN tbldraw
ON numbers_table.number = tbldraw.pick_1
OR numbers_table.number = tbldraw.pick_2
OR numbers_table.number = tbldraw.pick_3
OR numbers_table.number = tbldraw.pick_4
OR numbers_table.number = tbldraw.pick_5
GROUP BY number
ORDER BY number

How about a two step process? Assuming a table called summary_table ( int id, int ttl), for each number you care about...
insert into summary_table values (1,
(select count(*)
from table
where field1 = 1 or field2 = 1 or field3 = 1 or field4 = 1 or field5 = 1))
do that 59 times, once for each value. You can use a loop in most cases. Then you can select from the summary_table
select *
from summary_table
order by id
That will do it. I leave the coversion of this SQL into a stored procedure for those that know what database is in use.

The ALL() function, which returns true if the preceding operator is true for all parameters, makes the query particularly elegant and succinct.
To find the count a particular number (eg 3):
select count(*)
from tbldraw
where 3 = all (pick_1, pick_2, pick_3, pick_4, pick_5)
To find the count of all such numbers:
select pick_1, count(*)
from tbldraw
where pick_1 = all (pick_2, pick_3, pick_4, pick_5)
group by pick_1

Related

mysql select counts by if else condition

i have a table named cq500_all(to record diffrent doctor feedback)
now i want know counts when condition status is
field dr_1_finish and field dr_2_finish value is all fill 1
and
when field dr_1 different dr_2 (like dr_1=1 and dr_2=0,or dr_1=0 and dr_2=1 )
cause i want to know two doctors feedback counts (when different doctor's feedback on jpg)
for example image show CQ500-CT-1_36_08.jpg and CQ500-CT-1_36_09.jpg is match my select counts
it will be two (select counts result)
how to make the query on mysql?
You can count as
select count(*) as total
from cq500_all
where dr_1_finish = 1 and dr_2_finish = 1 and dr_1 != dr_2
You will got result in total
Pretty much just the way you've described it:
select *
from cq500_all
where dr_1_finish = 1 and dr_2_finish = 1
and dr_1 != dr_2
or (if dr_1 or dr_2 might not be just 0 and 1):
select *
from cq500_all
where dr_1_finish = 1 and dr_2_finish = 1
and ((dr_1 = 1 and dr_2 = 0) or (dr_1 = 0 and dr_2 = 1))

Conditional counting of consecutive rows

For a given current client i am trying to find how many consecutive years they have renewed a policy with us. My thinking on how to do this is to match a field in the current row with the previous row. I'm trying to write a function for this but if there is an easier way please let me know. Here is what i have for the function
Option Compare Database
'Renewal Count Returns count of consecutive renewals
Public Function RenewCount(strLocationID As Integer, _
strQuoteID As Integer, _
strOriginalQuoteID As Variant) As String
Static strLastLocationID As Integer
Static strLastQuoteID As Integer
Static strCount As Integer
If strLocationID = strLastLocationID And strOriginalQuoteID = strLastQuoteID Then
strCount = strCount + 1
Else
strLastLocationID = strLocationID
strLastQuoteID = strQuoteID
strCount = 0
End If
RenewCount = strCount
End Function
Here is a little sample of the data
LocationID QuoteID OriginalQuoteID
2 1094117
2 1125718 1094117
2 1148296 1125718
2 1176466 1148296
5 1031892
5 1044976 1031892
5 1059216 1044976
5 1077463 1059216
There are also dates for each policy that i can manipulate as well.
My idea would be to have the following and just find the max of the last column for each location.
LocationID QuoteID OriginalQuoteID Renewal_Count
2 1125718 1094117 0
2 1148296 1125718 1
2 1176466 1148296 2
5 1031892 0
5 1044976 1031892 1
5 1059216 1044976 2
5 1077463 1059216 3
5 1098124 1077463 4
5 1100215 0
5 1198714 1100215 1
5 1254125 1198714 2
Any help would be appreciated. Thanks
I forgot to mention that this has been sorted on the location ID and that OriginalQuoteID will be null for any New policy. When i try to run the function i get #num! in the column for a majority of the rows. What i want is for a given QuoteID the number of consecutive renewals there have been. So for the above for locationID 5 QuoteID 1254125 there have been 2 Renewals.
This might work (appears to be with my tests) - create a cartesian product on itself, link the QuoteID to the OriginaQuoteID and count.
SELECT T1.LocationID,
T1.QuoteID,
T1.OriginalQuoteID
FROM Table1 T1, Table1 T2
WHERE T1.QuoteID = T2.OriginalQuoteID
to get the count per LocationID (add 1 to count the Null field):
SELECT COUNT(*)+1
FROM Table1 T1, Table1 T2
WHERE T1.QuoteID = T2.OriginalQuoteID
GROUP BY T1.LocationID
or if you prefer joins:
SELECT COUNT(*)+1
FROM Table1 T1 INNER JOIN Table1 T2 ON T1.QuoteID = T2.OriginalQuoteID
GROUP BY T1.LocationID

how to search for a given sequence of rows within a table in SQL Server 2008

The problem:
We have a number of entries within a table but we are only interested in the ones that appear in a given sequence. For example we are looking for three specific "GFTitle" entries ('Pearson Grafton','Woolworths (P and O)','QRX - Brisbane'), however they have to appear in a particular order to be considered a valid route. (See image below)
RowNum GFTitle
------------------------------
1 Pearson Grafton
2 Woolworths (P and O)
3 QRX - Brisbane
4 Pearson Grafton
5 Woolworths (P and O)
6 Pearson Grafton
7 QRX - Brisbane
8 Pearson Grafton
9 Pearson Grafton
So rows (1,2,3) satisfy this rule but rows (4,5,6) don't even though the first two entries (4,5) do.
I am sure there is a way to do this via CTE's but some help would be great.
Cheers
This is very simple using even good old tools :-) Try this quick-and-dirty solution, assuming your table name is GFTitles and RowNumber values are sequential:
SELECT a.[RowNum]
,a.[GFTitle]
,b.[GFTitle]
,c.[GFTitle]
FROM [dbo].[GFTitles] as a
join [dbo].[GFTitles] as b on b.RowNumber = a.RowNumber + 1
join [dbo].[GFTitles] as c on c.RowNumber = a.RowNumber + 2
WHERE a.[GFTitle] = 'Pearson Grafton' and
b.[GFTitle] = 'Woolworths (P and O)' and
c.[GFTitle] = 'QRX - Brisbane'
Assuming RowNum has neither duplicates nor gaps, you could try the following method.
Assign row numbers to the sought sequence's items and join the row set to your table on GFTitle.
For every match, calculate the difference between your table's row number and that of the sequence. If there's a matching sequence in your table, the corresponding rows' RowNum differences will be identical.
Count the rows per difference and return only those where the count matches the number of sequence items.
Here's a query that implements the above logic:
WITH SoughtSequence AS (
SELECT *
FROM (
VALUES
(1, 'Pearson Grafton'),
(2, 'Woolworths (P and O)'),
(3, 'QRX - Brisbane')
) x (RowNum, GFTitle)
)
, joined AS (
SELECT
t.*,
SequenceLength = COUNT(*) OVER (PARTITION BY t.RowNum - ss.RowNum)
FROM atable t
INNER JOIN SoughtSequence ss
ON t.GFTitle = ss.GFTitle
)
SELECT
RowNum,
GFTitle
FROM joined
WHERE SequenceLength = (SELECT COUNT(*) FROM SoughtSequence)
;
You can try it at SQL Fiddle too.

MySQL String Comparison with Percent Output (Position Very Important

I am trying to compare two entries of 6 numbers, each number which can either can be zero or 1 (i.e 100001 or 011101). If 3 out of 6 match, I want the output to be .5. If 2 out of 6 match, i want the output to be .33 etc.
Note that position matters. A match only occurs when both entries have a 1 in the first position, both have a 0 in the second position etc.
Here are the SQL commands to create the table
CREATE TABLE sim
(sim_key int,
string int);
INSERT INTO sim (sim_key, string)
VALUES (1, 111000);
INSERT INTO sim (sim_key, string)
VALUES (2, 101101);
My desired output to compare the two strings, which share 50% of the characters, and output 50%.
Is it possible to do this sort of comparison in SQL? Thanks in advance
Have a look at this example.
CREATE TABLE sim (sim_key int, string int);
INSERT INTO sim (sim_key, string) VALUES (1, 111000);
INSERT INTO sim (sim_key, string) VALUES (2, 101101);
select a.string A, b.string B,
sum(case when Substring(A.string,Pos,1) = Substring(B.string,Pos,1) then 1 else 0 end) Matches,
count(*) as RowCount,
(sum(case when Substring(A.string,Pos,1) = Substring(B.string,Pos,1) then 1 else 0 end) /
count(*) * 100.0) as PercentMatch
from sim A
cross join sim B
inner join (
select 1 Pos union all select 2 union all select 3
union all select 4 union all select 5 union all select 6) P
on P.Pos between 1 and length(A.string)
where A.sim_key= 1 and B.sim_key = 2
group by a.string, b.string
It is crude and probably included more than required but shows how it can be done. It is better to create a numbers table with just numbers from 1 to 1000 or so, that can be used repeatedly in many queries where a number sequence is required. Such a table will replace the (select .. union virtual table used in the inner join)
Instead of keeping 10010101 as integer convert this binary version to true integer when compare use bit logic AND, result convert to binary and count '1' to how many match...
for convert: http://dev.mysql.com/doc/refman/5.5/en/binary-varbinary.html
for compare: http://dev.mysql.com/doc/refman/5.5/en/bit-functions.html bitwise AND
...

disperse relational structure of MySQL table

I have a table that consists of
id (auto_increment)
number int (can contain values from 10 to 12)
myvalue (varchar)
What I want to do is disperse the relational structure of this table for report purpose. I.e , I´d like to have something like:
id (auto_increment)
number10 (containing myvalue WHERE number=10)
number11 (containing myvalue WHERE number=11)
number12 (containing myvalue WHERE number=12)
I know that I can get the respective results by
SELECT myvalue FROM mytable WHERE number = 10;
but I haven´t figured out how to write these three SELECT statements into one single table or view.
thx for any help in advance!
Something like this maybe?:
SELECT
id,
IF(number=10, myvalue, NULL) AS number10,
IF(number=11, myvalue, NULL) AS number11,
IF(number=12, myvalue, NULL) AS number12
FROM mytable
This might do what you need. You've not explained it very well though so it might not!
SELECT user,
MIN(CASE WHEN number = 10 then myvalue end) AS number10,
MIN(CASE WHEN number = 11 then myvalue end) AS number11,
MIN(CASE WHEN number = 12 then myvalue end) AS number12
FROM table
WHERE number IN (10,11,12)
GROUP BY user
I don't get the "id number10 number11 number12" stuff, but if you want to select the rows with the number field matching a set of values, you can just do:
SELECT * FROM mytable WHERE number IN (10, 11, 12);
Or, alternatively, you can select a number range:
SELECT * FROM mytable WHERE number >= 10 AND number <= 12;
Edit 2:
Vin-G's got it. I was way off.