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
Related
i have 52k rows of records in my user table. In that table user_hash column having approximately 2000 duplicate values. i want to update user_hash columns 2nd duplicate value. The following table user_id (3, 10), (5, 14) having same value and i want to update user_id 10 and 14 values. how can i update it with MySQL Qry?
--------------------------------
user_id user_hash user_status
--------------------------------
1 ae57250b 1
2 310cb4e0 1
3 28b365c7 1
4 0073265b 1
5 8bec42a9 1
6 00a5c443 1
7 e1c27b19 1
8 993dc301 1
9 8fc8a6bf 1
10 28b365c7 1
11 194714c0 1
12 4611d83a 1
13 277a426b 1
14 8bec42a9 1
15 740c1412 1
... ... ...
... ... ...
... ... ...
The following qry which i have used to check duplicate entry
SELECT user_hash, COUNT(user_hash)
FROM user_data
GROUP BY user_hash
HAVING COUNT(user_hash) > 1;
The first thing that comes to mind is that you may want to define a constraint such that in the future you can't have non-unique values where you don't want them.
The second thing is to ensure that these hashes can't legitimately collide/overlap.
Those thoughts aside (as they may be irrelevant to your use case):
update user_data set user_data.user_hash = STORED_PROC_FOR_HASH()
from (
select *, row_number() over(partition by user_hash order by (select null)) row_num
from user_data
) user_data
where row_num > 1
Source for the above query: https://stackoverflow.com/a/25090251/3080207
As hinted at by Nick, you'll need to be able to generate a unique hash, which is pretty much the 2nd component to this problem.
Hopefully that is helpful.
Hi i need 5 rows count always in Mysql select query
I My current output is
my query
----------------------
$query = mysql_query("select * from table_name where MOBILE='$mobile_no' order by ID LIMIT 5 ");
----------------------
Result
----------------------
ARUN - 987654321
VINO - 987654321
RAJA - 987654321
-------------------
But I need like this (Need to return empty rows)
----------------------
ARUN - 987654321
VINO - 987654321
RAJA - 987654321
0 - 0
0 - 0
-------------------
So that I can create html table row (always 5 rows) text box with empty value inside the while loop ----- while($row=mysql_fetch_array($query))
You can use a loop in php and a counter in the loop. If the count is less then 5, then you fill the text box with nothing. It will give you something like that
$count = 0;
while($row=mysql_fetch_array($query)) {
// Fill your text box
$count+=1;
}
for($i=count; $i <= 5; $i++) {
// Fill your text box with empty string or whatever.
}
Since you requested a sql solution here it is: (but I do not recommend using it)
SELECT *
FROM (SELECT id, column1
FROM table_name
WHERE mobile = '$mobile_no'
UNION ALL
SELECT NULL, NULL FROM DUAL
UNION ALL
SELECT NULL, NULL FROM DUAL
UNION ALL
SELECT NULL, NULL FROM DUAL
UNION ALL
SELECT NULL, NULL FROM DUAL
UNION ALL
SELECT NULL, NULL FROM DUAL)
AS tab
order by tab.ID LIMIT 5
but you need to explicitly select all the columns from your table and in the select statements add as many NULL columns as you selected in your main statement. I didn't test it since I don't know your columns
simply add 2 more textboxes in html page. and not send any value or send null values in your database
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.
this is my table test
id identifier
--- ---------
1 zz
1 zzz
3 d
5 w
7 v
8 q
9 cc
9 ccc
here I want to remove the duplicate id's and keep the latest id's.
the identifier can have duplicate values it dose not matter but the id's should be unique.
I wrote this query to solve this problem but the problem is that it goes into a infinite loop.
please help me with this as I am not able to see the error.
Thanks
delete test
from test
inner join(
select max(id) as lastId, identifier
from test
where id in (
select id
from test
group by id
having count(*) > 1
)
group by id
)dup on dup.id = test.id
where test.id<dup.id
If you have an index on test(id, identifier), the following should be pretty efficient:
delete from test
where test.identifer < (select maxid
from (select max(identifier) as maxid from test t2 where t2.id = t.id
) a
)
The double nested query is a MySQL trick for referencing the update/delete table in the same query.
Look at How to delete duplicate rows with SQL?
And try this one(works for you want to do), i did with the identifier column, but with the date column as shown in the post is better.
DELETE FROM Test WHERE Identifier NOT IN
(SELECT MAX(Identifier) FROM Test GROUP BY Id);
Now with the DateField:
id identifier DateField
--- --------- ----------
1 zz 2013-02-01
1 zzz 2013-03-02
3 d 2013-03-02
5 w 2013-03-02
7 v 2013-03-02
8 q 2013-03-02
9 cc 2013-01-15
9 ccc 2013-03-02
that is the table, and row (1, zzz) is newer than (1,zz), you can know it by the DateField column, then this query deletes two rows (1, zz) and (9, cc) the oldest for Id's 1 and 9.
DELETE FROM Test WHERE Datefield NOT IN
(SELECT MAX(Datefield) FROM Test GROUP BY Id);
in SQL Server 2008 R2 i didnt get any error.
CREATE TEMPORARY TABLE tmp_tb_name AS
SELECT id,SUBSTRING_INDEX(GROUP_CONCAT(identifier ORDER BY id DESC),',',1)
FROM tb_name GROUP BY id ORDER BY NULL;
TRUNCATE TABLE tb_name;
INSERT INTO tb_name SELECT tmp_tb_name;
DROP TEMPORARY TABLE IF EXISTS tmp_tb_name;
Update
I have found a solution for the issue: This is how I did it to solve the issue
This is the solution which worked for me when there are millions on entities in the table.
Any other SQL query is creating a lot of processes and burdening the server.
$i=0;
while($i<10)
{
$statement="SELECT *
FROM test
WHERE id = :i";
$query=$db->prepare($statement);
$query->bindParam(':i',$i,PDO::PARAM_INT);
$query->execute();
$results=$query->fetchAll(PDO::FETCH_ASSOC);
$c=count($results);
$temp=$results[$c-1];
$statement="DELETE FROM test WHERE id= :i";
$query=$db->prepare($statement);
$query->bindParam(':i',$i,PDO::PARAM_INT);
$query->execute();
$statement="Insert into test values(:id,:identifier)";
$query=$db->prepare($statement);
$query->bindParam(':id',$temp['id'],PDO::PARAM_INT);
$query->bindParam(':identifier',$temp['identifier'],PDO::PARAM_STR);
$query->execute();
$results=$query->fetchAll(PDO::FETCH_ASSOC);
$i++;
}