I have the following table structure:
CREATE TABLE test(
myID INT,
num1 INT,
num2 INT,
num3 INT,
PRIMARY KEY (myID)
)engine=innodb;
now i have the following data in the table:
myID num1 num2 num3
1 15 27 98
2 27 38 66
3 15 27 77
now i need to run 2 queries, first query runs to select all numbers and on PHP side i count the number of times each number appeared (frequencies), the second query should select the second most frequent number.
First query:
$numfreq = PDO->prepare('
SELECT num1, num2, num3
FROM test
');
$numfreq->execute();
$allNums = array();
while ($row = $numfreq->fetch(PDO::FETCH_ASSOC)) {
$allNums[] = intval($row['num1']);
$allNums[] = intval($row['num2']);
$allNums[] = intval($row['num3']);
}
$numFrequencies = array_count_values($allNums);
arsort($numFrequencies);
this correctly returns frequencies of each number from the table. Now for the second part
THIS IS WHERE I NEED HELP:
I get the most frequent appeared number in this case its 27 since its frequency is 3, I need to select that 1 number that appears the most next to 27 means i need to get somehow number 15 since it appears twice next to 27.
i can probably figure out algorithm on PHP side but i was wondering if its possible to do it using query?
so the final result would be:
most frequent number: 27
most frequent number 27 combined with 15 appears 2 times and is most frequent combination.
select val, count(val) as frequency
from
(select num1 as val from test
union all
select num2 as val from test
union all
select num3 as val from test
) as b
group by val
order by frequency desc
limit 2
Sqlfiddle here.
The inner query converts the three columns into a result set with just one column - highlight the inner query, and you'll see how it works. We then use that result set as the source for the counting/ordering query.
Related
I'm looking to find the lowest missing number between 2 numbers.
there may be jumps between 3080 and 3085, etc and all I would need is 3081.
This is for assigning an id to an entry and these entries can be deleted thus the id is too and because we have a limited range we want to make sure we use all the numbers. So if there aren't any missing numbers it would have to grab the next available number. if it's full till 3850 then it would need to grab 3851.
They are 0 if they have been deleted rather than null if that helps.
SELECT number, user_id
FROM entries
WHERE user_id = '18'
AND number BETWEEN '3000' AND '4000'
I'm not sure how to get the lowest available number in this sequence, please help. Thank you.
Try using a self join:
SELECT MIN(e1.number) + 1 num_missing
FROM entries e1
LEFT JOIN entries e2
ON e2.number = e1.number + 1
WHERE e1.id = 18 AND e1.number BETWEEN 3000 AND 4000 AND
e2.number IS NULL;
The critical condition in the WHERE clause is e2.number IS NULL, which means that this particular number had no next immediate value in the sequence, i.e. it is the start of a gap.
If you want next missing number for an id, then:
select e.id, e.number + 1
from entries e
where not exists (select 1
from entries e2
where e2.id = e.id and e2.number = e.number + 1
);
If you want this for a particular id, then add id = 18 to the outer where clause.
I have a complicated request. I have to make a report in PHP like the picture below.
Part summarized yield must be filled with across calculation.
Like I explain in formula column, value in part summarized yield got from calculation between location yield and part summarized yield.
(See this formula)
How to do that calculation in a PHP report?
I already tried using a cursor, but it still did not work.
Here is my cursor calculation:
--In PHP file, i make query to insert data first to table tyield_summary
--Cursor to input yield_summary
Declare #nourut varchar(2), #maxnourut varchar(2), #bpnum varchar(20), #pnum varchar(20), #curnourut varchar(2), #psum decimal(18,2), #ysum decimal(18,2)
DECLARE StockCursor CURSOR
FOR
select no_urut, part_number, Part_Summary
from tyield_summary
where no_urut<>'99'
order by part_number desc, no_urut asc
set #bpnum=''
OPEN StockCursor
FETCH NEXT FROM StockCursor INTO #nourut, #pnum, #psum
WHILE ##FETCH_STATUS=0
BEGIN
if #bpnum=#pnum
begin
select top 1 #curnourut=no_urut
from tyield_summary
where part_number=#pnum
and no_urut<#nourut
order by no_urut desc
set #bpnum=#pnum
select #maxnourut = max(no_urut) from tyield_summary
where part_number=#pnum
update tyield_summary
set yield_summary = case when Part_Summary=0 then #psum else (Part_Summary*#psum)/100 end
where part_number=#pnum
and no_urut=#curnourut
end
else
begin
set #bpnum=#pnum
end
FETCH NEXT FROM StockCursor INTO #nourut, #pnum, #psum
END
CLOSE StockCursor
DEALLOCATE StockCursor
Here table structure :
I need to fill part_summary field using formula that i show in excel.
In formula show, calculation using cross field.
Here is how you can do it (without nasty cursors).
Just use row number over your ordering/aggregation criteria to find the next row,
left join each row with its next (not forgetting the aggregation criteria) and it's done.
Let's use an example (and here is how you properlu post a table structure):
create table Lazydude
(
Partno varchar(20) not null
,Seq int not null
,[Value] float not null
)
GO
insert into Lazydude (Partno, Seq, [Value])
values
('AAA', 1, 77.7)
,('BBB', 0, 2)
,('BBB', 3, 3)
,('BBB', 9, 5)
,('CCC', 1, 33.3)
,('CCC', 2, 33.3)
GO
and to select using row number and use the result in a self-join
with Temp as(
select Partno, Seq, [Value]
,ROW_NUMBER() OVER(ORDER BY Partno, Seq) AS [Row]
from Lazydude
)
select t0.Partno, t0.Seq, t0.[Value], t0.[Row]
, t1.row as [Next Row], t1.[Value] as [Next Value]
, case when t1.row is null
then t0.[Value]
else t0.Value * t1.Value
end as [The Calculation]
from Temp t0
left join Temp t1 on t1.[Row] = t0.[Row] + 1 and t1.Partno = t0.Partno
You can see the results in the SQL Fiddle
Partno Seq Value Row Next Row Next Value The Calculation
AAA 1 77.7 1 (null) (null) 77.7
BBB 0 2 2 3 3 6
BBB 3 3 3 4 5 15
BBB 9 5 4 (null) (null) 5
CCC 1 33.3 5 6 33.3 1108.8899999999999
CCC 2 33.3 6 (null) (null) 33.3
I have an SQL database with I'm calling through a php file. The column can contain both numbers and words. For example it could countain:
1
4
clowns
12
46
Naturally, ORDER BY returns:
1
12
4
46
clowns
but I would like it to sort how it would sort integers with the numbers:
1
4
12
46
clowns
Is it possible to do this?
add some new columns to solve this, first order by whether or not it is a number, then by the number value, and finally alphabetically by the word value.
In MSSQL you have access to the isnumeric function.
In ORACLE you could create a custom function using THIS
In MYSQL you could create a custom function using THIS
select your_column from(
select *,
isnumeric(your_column) as ISNUMBER,
CASE WHEN ISNUMERIC(your_column) = 1 THEN CAST(your_column AS INT) ELSE null END as NUMBERVALUE,
case when isnumeric(your_column) = 1 then null else your_column end as TEXTVALUE )
order by isnumber desc, numbervalue asc, textvalue asc
...
I am recording a real time change of a given signal into my database table.
Then I draw line graph to visualize the change of the signal level.
I want to get (10n+1)th rows in the table to make a rough graph. 10 is also arbitrary. User may change it to another value.
Does someone know how to make this just using a MySQL Query
If no, I will go with PHP after selecting all the data.
Here my table structure is:
|id |signal1 |signal2 | signal 3 |
+----------+----------+----------+------------+
|1 |0.41452 | 1.32135 | 0.31231 |
...
If you have an auto_incrememt id column, you can select rows that are divisible by n
SELECT * FROM tableName1 WHERE MOD(id,10)=0;
// id divided by 10 with a remainder equal to 0 (exact)
or without sequential column id's
SELECT * FROM (
SELECT
#row := #row +1 AS rowNum, colName1
FROM (
SELECT #row :=0) r, tableName1
) ranked
WHERE rowNum % 10 = 1
If your table has auto increment id (intID), then you should try this code.There are only 26 records in my table.
select * from tablename where intId
in (select case (intId%10=0) when 1 then intId else 0 end as x from tablename )
Output :-
10 sdf KK201300010 123456 Regular
20 sdf KK201300020 123456 Regular
It will displaying each record in every 10 record.
Hope it will help you.
Table structure:
MyTable (
ID INT AUTO_INCREMENT,
Num1 INT,
Num2 INT,
Num3 INT,
Num4 INT,
PRIMARY KEY(ID)
)engine=InnoDB;
Now i have around 20-30k records. Num1, Num2, Num3 and Num4 are just some random numbers. Im trying to select 2 and 3 number combinations from this table. For example lets say i have the following rows in table:
ID Num1 Num2 Num3 Num4
1 20 11 9 150
2 30 11 20 19
3 40 45 11 20
I would want to select the most frequently used 2 number combinations and then 3 number combinations. So note that 20 and 11 appear 3 times in table means the combination 20,11 or 11,20 doesnt matter the order has count 3 and so on for other combinations.
I want to retrieve this data in PHP array so that i can do some calculations or display on screen.
What i tried so far:
SELECT *
FROM MyTable
WHERE (Num1 = :num1 AND Num2 = :num2) OR (Num1 = :num1 AND Num3 = :num2) OR
(Num1 = :num1 AND Num4 = :num2) OR (Num2 = :num1 AND Num1 = :num2) OR
(Num2 = :num1 AND Num3 = :num2) OR (Num2 = :num1 AND Num4 = :num2) OR
***
***
and so on for all combinations. Now this gets annoying if i try to use it for 3 number combinations.
Is there a better and efficient way of doing this?
Do i need to restructure table to make this easier?
Will restructured table be normalized? (Right now i think is normalized if not please tell me)
Case 2 combinations
I think you should consider store information in a big matrix like this:
num times_appearing_with_number_1 times_appearing_with_number_2 ...
For a case like
1 8 2 3
1 7 23 24
it would be like:
num 1 2 3 4 5 6 ...
1 - 1 1 0 0 0 ...
2 1 - 1 0 0 0 ...
And then you check which lines have bigger numbers. The indexes would be useful to get the number it corresponds to.
Case 3 combinations
The same with a 3D-matrix.
To feed these tables you should only fetch the information from MySQL and then loop.
since the order of values doesn't matter, there are only 6 permutations to pick two out of four columns (c1-c2, c1-c3, c1-c4, c2-c3, c2-c4 and c3-c4), and only four permutations to pick three (c1-c2-c3, c1-c2-c4, c1-c3-c4, c2-c3-c4).
One approach would be to create a temporary table which contains the id of the row and all 6 (4 for three cols) permutations of those values. You could use a query like this:
SELECT id, CASE Num1<=Num2 WHEN TRUE THEN CONCAT(Num1,"-",Num2) ELSE CONCAT(Num2,"-",Num1) END FROM MyTable
UNION
SELECT id, CASE Num1<=Num3 WHEN TRUE THEN CONCAT(Num1,"-",Num3) ELSE CONCAT(Num3,"-",Num1) END FROM MyTable
...
All that's left then is counting the number of matching rows (note that above query could either be run manually or as a subquery to the counting query)
Edit: Something to fiddle with.