Given the data table below, how can I retrieve only the row #3, querying the field "chave", based on multiple json rows?
I want to retrieve the master row where the json field (NomeCampo = id and Valor = 3) and also (NomeCampo = id2 and Valor = 5)
id id_modulo chave
624D4FB5-6197-11EA-A947-9C5C8ED7177E 17 [{"NomeCampo":"id","Valor":2},{"NomeCampo":"id2","Valor":5}]
4CF95795-4BFD-EC11-8CE5-80A589B639E0 17 [{"NomeCampo":"id","Valor":3},{"NomeCampo":"id2","Valor":4}]
DBE9275A-9BFF-EC11-8CE5-80A589B639E0 17 [{"NomeCampo":"id","Valor":3},{"NomeCampo":"id2","Valor":5}]
BE3228C6-9BFF-EC11-8CE5-80A589B639E0 17 [{"NomeCampo":"id","Valor":3},{"NomeCampo":"id2","Valor":6}]
This is the SQL that I have but it is not retrieving any row at all:
SELECT id, id_modulo, chave
FROM myTable
WHERE id_modulo = 17
AND EXISTS (SELECT *
FROM OPENJSON(chave)
WITH (NomeCampo nvarchar(max) '$.NomeCampo',
Valor nvarchar(max) '$.Valor') AS [Info]
WHERE ([Info].NomeCampo = 'id' AND [Info].Valor = '3')
AND ([Info].NomeCampo = 'id2' AND [Info].Valor = '5'))
Is this even possible to do?
This is actually a case of relational division. You need to find the set of JSON rows which have these properties, so you need to group it
SELECT
t.id,
t.id_modulo,
t.chave
FROM myTable t
WHERE t.id_modulo = 17
AND EXISTS (SELECT 1
FROM OPENJSON(t.chave) WITH (
NomeCampo nvarchar(100),
Valor nvarchar(1000)
) AS Info
WHERE (Info.NomeCampo = 'id' AND Info.Valor = '3'
OR Info.NomeCampo = 'id2' AND Info.Valor = '5')
GROUP BY ()
HAVING COUNT(*) = 2
);
Another option
SELECT
t.id,
t.id_modulo,
t.chave
FROM myTable t
WHERE t.id_modulo = 17
AND EXISTS (SELECT 1
FROM OPENJSON(t.chave) WITH (
NomeCampo nvarchar(100),
Valor nvarchar(1000)
) AS Info
GROUP BY ()
HAVING COUNT(CASE WHEN Info.NomeCampo = 'id' AND Info.Valor = '3' THEN 1 END) > 0
AND COUNT(CASE WHEN Info.NomeCampo = 'id2' AND Info.Valor = '5' THEN 1 END) > 0
);
This is My Data:
I want select data Like This ▼
I try select that in group by but is not individually data show.
and this is my code
select
date_format((select receive_contract_datetime from worklist_info where id = worklist_id), '%y.%m.%d') as receive_datetime,
(select trade_name from trade_info where id = (select worklist_trade_id from worklist_info where id = worklist_id)) as trade_name,
(select staff_name from staff_info where id =
(select account_staff_id from account_info where id =
(select worklist_account_id from worklist_info where id = worklist_id))) as worklist_writer,
date_format((select worklist_output_plan_date from worklist_info where id = worklist_id), '%y.%m.%d') as output_plan_date,
(select worklist_project_name from worklist_info where id = worklist_id) as prj_name,
worklist_sub_process_id,
count(worklist_sub_process_id),
sum(worklist_sub_state),
-- (sum(worklist_sub_process_id = 1)*2) as laser_count, worklist_sub_state
-- sum(worklist_sub_process_id = 1) as laser_count,
-- if(sum(worklist_sub_process_id = 1) > 0,count(IF(worklist_sub_process_id = 1, if(worklist_sub_state = 0,1,null), null)),-1) as laser_wait,
-- if(sum(worklist_sub_process_id = 1) > 0,count(IF(worklist_sub_process_id = 1, if(worklist_sub_state = 1,1,null), null)),-1) as laser_run,
-- if(sum(worklist_sub_process_id = 1) > 0,count(IF(worklist_sub_process_id = 1, if(worklist_sub_state = 2,1,null), null)),-1) as laser_end,
(select worklist_comment from worklist_info where id = worklist_id) as worklist_comment,
(select worklist_lot from worklist_info where id = worklist_id) as lot_number
from worklist_info_sub group by worklist_id,worklist_sub_process_id;
You seem to pivot your dataset. For this, you can use conditional aggregation:
select col_master_id,
sum(col_semi_id = 1) as col_semi_1_count,
sum(case when col_semi_id = 1 then col_state else 0 end) as col_semi_1_state,
sum(col_semi_id = 2) as col_semi_2_count,
sum(case when col_semi_id = 2 then col_state else 0 end) as col_semi_2_state,
sum(col_semi_id = 3) as col_semi_3_count,
sum(case when col_semi_id = 3 then col_state else 0 end) as col_semi_3_state,
from mytable
group by col_master_id
I don't see how your query relates to your data. This answer is based on your sample data and desired results, not on your query.
CLOSED. I had a mistake somewhere else unrelated to the boolean.
What am I doing wrong here in this SQL where:
WHERE (country = 'HK') OR (country = 'TW') OR (country = 'AX')
It’s missing the result for AX in the output.
What am I doing wrong with this Boolean expression?
Note1. ' at end of AX was my typo here. I corrected above.
Full code here
$myresult = mysqli_query($GLOBALS['DBlink'],
"SELECT $getcolumn
FROM levermann
WHERE
( $sqlwhere2 ) AND
levermann.`WEEK` =
(SELECT `WEEK`, COUNT(*) AS cc
FROM levermann
WHERE ( $sqlwhere2 )
GROUP BY `WEEK`
HAVING cc > 4
ORDER BY `WEEK` DESC
LIMIT 1 )
AND $lswitch AND $marketcap
ORDER BY LScore2 DESC, MarketCAPUSD DESC, Stock_Short ASC
LIMIT 10;");
if ($region == 'ASIA') {
$sqlwhere2 = "
( country = 'HK' ) OR
( country = 'TW' ) OR
( country = 'AX' ) OR
( country = 'KS' ) OR
( country = 'SS' )";
$region='Asia';
}
if ($region == 'Global') {
$sqlwhere2 = " country like '%'";
$region='Global';
}
if ($region == 'US') {
$sqlwhere2 = " country = 'US'";
$region='US';
}
There is a special character at the end enclosing 'AX‘
Also why not just use in() instead?
WHERE country in ('HK','TW','AX')
Entire statement should be in brackets
Edit: also wrong quote at the end
WHERE (country = 'HK' OR country = 'TW' OR country = 'AX')
you have error in the condition
(country = 'AX‘)
you are not using the ending '' correctly.please correct and check it
This is my mysql query
SELECT a.model_name,
IF( b.officially_released_year = '".$currentyear."',1,0 ) AS release_year,
IF( b.officially_released_month = '".$first_month."' OR b.officially_released_month = '".$second_month."' OR b.officially_released_month = '".$third_month."' OR b.officially_released_month = '".$currentmonth."' ,1,0) AS release_month
FROM ".TBL_CAR_ADD_MODELS." a, ".TBL_CAR_SPEC_GENERAL." b
WHERE a.model_id = b.model_id AND a.model_status = '1'
ORDER BY a.model_created_on DESC
I want to do one more filtering option in this query. I need to get the records based on release_year = 1 & release_year = 1. I have done release_year and release_month columns through IF STATEMENT in MYSQL QUERY
release_year
IF( b.officially_released_year = '".$currentyear."',1,0 ) AS release_year
release_month
IF( b.officially_released_month = '".$first_month."' OR b.officially_released_month = '".$second_month."' OR b.officially_released_month = '".$third_month."' OR b.officially_released_month = '".$currentmonth."' ,1,0) AS release_month
How do I get the records based on these values (release_month = 1 & release_year = 1) in this query? I have tried WHERE release_month = 1 AND release_year = 1 but this one returns unknown column
You could do this:
SELECT
*
FROM
(
SELECT
a.model_name,
a.model_created_on,
IF( b.officially_released_year = '".$currentyear."',1,0 ) AS release_year,
IF( b.officially_released_month = '".$first_month."' OR b.officially_released_month = '".$second_month."' OR b.officially_released_month = '".$third_month."' OR b.officially_released_month = '".$currentmonth."' ,1,0) AS release_month
FROM ".TBL_CAR_ADD_MODELS." a, ".TBL_CAR_SPEC_GENERAL." b
WHERE a.model_id = b.model_id AND a.model_status = '1'
) AS tbl
WHERE tbl.release_year=1 AND release_month=1
ORDER BY tbl.model_created_on DESC
I have a table that look like this:
Company Year Revenue Cost Profit
ABC 1 10 6 4
ABC 2 12 7 5
ABC 3 14 8 6
XYZ 1 25 18 7
XYZ 2 27 19 8
XYZ 3 29 20 9
I want it look like this:
Company Item 1 2 3
ABC Revenue 10 12 14
ABC Cost 6 7 8
ABC Profit 4 5 6
XYZ Revenue 25 27 29
XYZ Cost 18 19 20
XYZ Profit 7 8 9
A crosstab query only allows one value. I can do it using separate crosstab queries for Revenue, Cost And Profit and the combine using the Union function but there must be an easier way.
Any help would be really appreciated.
Max
Variation for you to try.
SELECT Company,
item,
SUBSTRING_INDEX(SUBSTRING_INDEX(item_details, ',', 1), ',', -1) AS `1`,
SUBSTRING_INDEX(SUBSTRING_INDEX(item_details, ',', 2), ',', -1) AS `2`,
SUBSTRING_INDEX(SUBSTRING_INDEX(item_details, ',', 3), ',', -1) AS `3`
FROM
(
SELECT Company, 'Revenue' AS item, GROUP_CONCAT(Revenue ORDER BY `Year`) AS item_details
FROM SomeTable
GROUP BY Company
UNION
SELECT Company, 'Cost' AS item, GROUP_CONCAT(Cost ORDER BY `Year`)
FROM SomeTable
GROUP BY Company
UNION
SELECT Company, 'Profit' AS item, GROUP_CONCAT(Profit ORDER BY `Year`)
FROM SomeTable
GROUP BY Company
) Sub1
ORDER BY Company, FIELD(Item, 'Revenue', 'Cost', 'Profit')
SQL fiddle for you:-
http://www.sqlfiddle.com/#!2/995a0/6
For reasons of scalability (and flexibility), problems like this are best left to the application level code (e.g. a simple PHP loop on a well-ordered result set) but, just for fun...
SELECT company
, item
, MAX(CASE WHEN year = 1 THEN value END) y1
, MAX(CASE WHEN year = 2 THEN value END) y2
, MAX(CASE WHEN year = 3 THEN value END) y3
FROM
( SELECT company, year, 'revenue' item, revenue value FROM my_table
UNION
SELECT company, year, 'cost',cost FROM my_table
UNION
SELECT company, year, 'profit',profit FROM my_table
) x
GROUP
BY company
, item
ORDER
BY company
, FIELD(item,'Revenue','Cost','Profit');
Try this:
SELECT Company, Item, Col1 AS 1, Col2 AS 2, Col3 AS 3
FROM (SELECT a.Company, 'Revenue' AS Item, MAX(IF(a.Year = 1, a.Revenue, 0)) AS Col1,
MAX(IF(a.Year = 2, a.Revenue, 0)) AS Col2, MAX(IF(a.Year = 3, a.Revenue, 0)) AS Col3
FROM tableA a
GROUP BY a.Company
UNION
SELECT a.Company, 'Cost' AS Item, MAX(IF(a.Year = 1, a.Cost, 0)) AS Col1,
MAX(IF(a.Year = 2, a.Cost, 0)) AS Col2, MAX(IF(a.Year = 3, a.Cost, 0)) AS Col3
FROM tableA a
GROUP BY a.Company
UNION
SELECT a.Company, 'Profit' AS Item, MAX(IF(a.Year = 1, a.Profit, 0)) AS Col1,
MAX(IF(a.Year = 2, a.Profit, 0)) AS Col2, MAX(IF(a.Year = 3, a.Profit, 0)) AS Col3
FROM tableA a
GROUP BY a.Company
) AS A
ORDER BY Company, FIELD(Item, 'Revenue', 'Cost', 'Profit')
A second way of doing it. Not tested (so probably some typos), but doing some SQL to get the data then looping around the details, lobbing them to an object to put out the rows. This will cope with any where a company is missing a data for a year.
Note that you could greatly simplify the SQL if you had a table of years that you are interested in and a table of companies.
<?php
$sql = "SELECT Sub1.Year, Sub2.Company, IFNULL(SomeTable.Revenue, 0) AS aValue, 'Revenue' AS Item
FROM
(
SELECT DISTINCT Year FROM SomeTable
) Sub1
CROSS JOIN
(
SELECT DISTINCT Company FROM SomeTable
) Sub2
LEFT OUTER JOIN SomeTable
ON Sub1.Year = SomeTable.Year
AND Sub2.Company = SomeTable.Company
UNION
SELECT Sub1.Year, Sub2.Company, IFNULL(SomeTable.Cost, 0) AS aValue, 'Cost' AS Item
FROM
(
SELECT DISTINCT Year FROM SomeTable
) Sub1
CROSS JOIN
(
SELECT DISTINCT Company FROM SomeTable
) Sub2
LEFT OUTER JOIN SomeTable
ON Sub1.Year = SomeTable.Year
AND Sub2.Company = SomeTable.Company
UNION
SELECT Sub1.Year, Sub2.Company, IFNULL(SomeTable.Profit, 0) AS aValue, 'Profit' AS Item
FROM
(
SELECT DISTINCT Year FROM SomeTable
) Sub1
CROSS JOIN
(
SELECT DISTINCT Company FROM SomeTable
) Sub2
LEFT OUTER JOIN SomeTable
ON Sub1.Year = SomeTable.Year
AND Sub2.Company = SomeTable.Company
ORDER BY Company, FIELD(Item, 'Revenue', 'Cost', 'Profit'), Year";
$query = $db->query($sql) or die($db->error()) ;
if ($row = $this->db->fetchAssoc())
{
echo "<table>";
$PrevCompany = $row['Company'];
$PrevItem = $row['Item'];
$aLine = new ProcessLine($PrevCompany, $PrevItem, true);
do
{
if ($PrevCompany != $row['Company'] or $PrevItem != $row['Item'])
{
unset($aLine);
$PrevCompany = $row['Company'];
$PrevItem = $row['Item'];
$aLine = new ProcessLine($PrevCompany, $PrevItem);
}
$aLine->Assign_Detail($row['Year'], $row['aValue'])
} while($row = $this->db->fetchAssoc());
unset($aLine);
echo "</table>";
}
class ProcessLine
{
private $Company;
private $Item;
private $row_details = array();
private $FirstRow = false
public __CONSTRUCT($Company, $Item, $FirstRow=false)
{
$this->Company = $Company;
$this->Item = $Item;
}
public __DESTRUCT()
{
if ($this->Firstrow)
{
echo "<tr><th>".$this->Company."</th><th>".$this->Item."</th>";
foreach($row_details AS $row_year=>$row_value)
{
echo "<th>$row_year</th>";
}
echo "</tr>";
}
echo "<tr><td>".$this->Company."</td><td>".$this->Item."</td><td>".implode("</td><td>", $row_details)."</td></tr>";
}
public Assign_Detail($in_year, $in_value)
{
$row_details[$in_year] = $in_value;
}
}
?>