MySQL query to get count in a range - mysql

A snapshot of my DB
I want to get count of pcl_No present in a specified range( SUM(tv_land + tv_imp))
I have written a query but I am getting Invalid use of group error
select
count(CASE WHEN sum(tv_land+tv_imp) BETWEEN 0 AND 10000 THEN 1 END) as count0_10000
from
tax_l2006
where red_date = 0
GROUP BY pcl_no
Sample Output
0-10000 10000-20000 30000-40000 >40000
2 3 1 8

I think you just want:
select count(CASE WHEN tv_land + tv_imp BETWEEN 0 AND 10000 THEN 1 END) as count0_10000
from tax_l2006
where red_date = 0;
I would write this in MySQL more simply as:
select sum( (tv_land + tv_imp) between 0 and 10000 ) as count0_10000
from tax_l2006
where red_date = 0;
MySQL treats a true boolean as "1" in a numeric context and "0" for false, so summing the boolean is counting the number of times it is true.
You can follow the same pattern for the rest of the columns.
If pcl_no is not unique and you need to sum the values, then you would use a subquery:
select sum(total between 0 and 10000) as count0_10000
from (select pcl_no, sum(tv_land + tv_imp) as total
from tax_l2006
where red_date = 0
group by pcl_no
) p;
However, your data suggests that the column is unique, so the additional aggregation is not necessary.

Related

MySql: Order randomly when order is 0, but use numbers before

I have this table
And I wanna retrieve all data but in a certain order. I want it to be orderd by the field order, but with 0 meaning at random and AFTER the actual numbers in that field have been ordered.
So if I did this:
var sqlString = "SELECT * \
FROM 10561_13581_tblOffers \
WHERE isVisible = 1 \
LIMIT " + start + "," + count
I want the result to be either:
"bücher oder so" - order 1
"frau mit haar" - order 3
"stein" - order 0
"ordermy" - order 0
OR the last two reversed, as they are supposed to be randomly ordered
"bücher oder so" - order 1
"frau mit haar" - order 3
"ordermy" - order 0
"stein" - order 0
But in both cases, order 1 and 3 are in order.
How would I make my query to have the desired result?
(ofc, this can be done with a lot more order numbers and a lot more rows with a 0 for order)
The boolean expression order = 0 is evaluated as 1 for true or 0 for false and can be used in the ORDER BY clause:
SELECT *
FROM 10561_13581_tblOffers
WHERE isVisible = 1
ORDER BY `order` = 0, --this will send all 0s at the end of the resultset
`order`
If you actually want all 0s to be sorted randomly you can add RAND() function:
ORDER BY `order` = 0,
`order`,
RAND()
You can use
ORDER BY CASE
WHEN order = 0 THEN 99999999
ELSE order END
like that the 0's will come at the end in no particular order.

how to sum after iff condition in ssrs?

I want to sum all the values of the column, using if condition same as the column expression:-
The Expression of the normal column:-
iif(Fields!mcount.Value <> 0 And Fields!TaxCode.Value = 1 ,Fields!InputAmnt.Value,0)
The Expression to sum, I used 2 codes and the same result "#Error" appeared in both cases
sum(iif(Fields!mcount.Value <> 0 And Fields!TaxCode.Value = 1 ,Fields!InputAmnt.Value,0))
and
iif(Fields!mcount.Value <> 0 And Fields!TaxCode.Value = 1 ,sum(Fields!InputAmnt.Value),0)
any help ?
Try adding VAL from the InputAmnt field. See below expression.
=SUM(iif(Fields!mcount.Value <> 0 And Fields!TaxCode.Value = 1 ,VAL(Fields!InputAmnt.Value),0))

How can I count the number of a value in a particular row using SQL?

Database
id decline maintaining losing
1 true false true
2 false false false
3 true true false
I want to count the number of true values based on the id using a SQL statement.
If this are all the columns there are, then use this:
SELECT id,
(case when decline = 'true' then 1 else 0 end) +
(case when maintaining= 'true' then 1 else 0 end) +
(case when losing= 'true' then 1 else 0 end) as HowMuchTrue
FROM YourTable
select sum(if(maintaining = 'true', 1, 0)) from table -- and here some conditions.
In MySQL, in case of boolean fields you can directly add them together:
SELECT id, decline + maintaining + losing
FROM mytable
Demo here
The question seems to be a little fuzzy, but I think I know what you are going for. For each row, you want to count the number of times "true" shows up in them.
To do so, we'll use a CASE statement to processes true into ones, and false into zeros
SELECT
id,
CASE
WHEN decline = 'true' THEN 1
WHEN decline = 'false' THEN 0
else 'check your logic'
END as decline_processed,
CASE
WHEN maintaining = 'true' THEN 1
WHEN maintaining = 'false' THEN 0
else 'check your logic'
END as maintaining_processed,
CASE
WHEN losing = 'true' THEN 1
WHEN losing = 'false' THEN 0
else 'check your logic'
END as losing_processed
FROM
[table]
This gets us the following results:
id, decline_processed, maintaining_processed, losing_processed
1 , 1, 0, 1
2, 0, 0, 0
3, 1, 1, 0
From here, we can take the results and gather them and get sums for each row.
SELECT
id,
SUM(query_result_alias.decline_processed
+ query_result_alias.maintaining_processed
+ query_result_alias.losing_processed
) as number_of_true_values
FROM
[query with case statement above] as query_result_alias
GROUP BY
query_result_alias.id
This will get these results, which I believe answers your question:
id, number_of_true_values
1, 2
2, 0
3, 2
Bonus, we can process the result into summary data
SELECT
COUNT(query_result_alias2.id) as counter,
query_result_alias2.number_of_true_values
FROM
[query with case statement above] as query_result_alias2
GROUP BY
query_result_alias2.number_of_true_values
This gets you the number of rows that have each number of true values:
counter, number_of_true_values
2, 2
1, 0
With the sample data, you will only have two results, but larger datasets would provide all of the options.

Error 1366 - Incorrect decimal value: '' for column '' at row -1

I've got a rather large query that is trying to get a list of carriers and compare the amount of insurance they have on record to identify carriers that do not meet a minimum threshold. If I run the select query it works just fine with no errors. But when I try to use it for an insert into a table it returns this error message
[Err] 1366 - Incorrect decimal value: '' for column '' at row -1
I have to use the cast as decimal at the bottom of this query because the value that is being stored in the database is a varchar and I cannot change that.
Anyone have any ideas?
set #cw_days = 15;
INSERT INTO carrier_dnl (carrier_id, dnl_reason_id, status_id)
SELECT work_cw_carrier_status_update.carrier_id, company_dnl_schema.dnl_reason_id,
CASE
WHEN work_cw_carrier_status_update.comparison_date > #cw_days THEN 1
ELSE 4
END as status
FROM work_cw_carrier_status_update
JOIN company_dnl_schema
ON company_dnl_schema.dnl_reason_id = 51
LEFT OUTER JOIN carrier_insurance
ON carrier_insurance.carrier_id = work_cw_carrier_status_update.carrier_id
WHERE ifnull(carrier_insurance.insurance_type_id,4) = 4
AND date(now()) BETWEEN IFNULL(carrier_insurance.insurance_effective_date,DATE_SUB(now(),INTERVAL 1 day)) AND IFNULL(carrier_insurance.insurance_expiration_date,DATE_ADD(now(),INTERVAL 1 day))
AND CASE WHEN NULLIF(carrier_insurance.insurance_bipdto_amount,'') is null THEN 0 < company_dnl_schema.value
ELSE
ifnull(cast(replace(carrier_insurance.insurance_bipdto_amount, '*','') as decimal),0) < company_dnl_schema.value
END
AND ( work_cw_carrier_status_update.b_bulk = 0 OR work_cw_carrier_status_update.b_bulk = 1 )
AND ( work_cw_carrier_status_update.b_otr = 1 OR work_cw_carrier_status_update.b_ltl = 1
OR work_cw_carrier_status_update.b_dray = 1 OR work_cw_carrier_status_update.b_rail = 1
OR work_cw_carrier_status_update.b_intermodal = 1 OR work_cw_carrier_status_update.b_forwarder = 1
OR work_cw_carrier_status_update.b_broker = 1 )
group by work_cw_carrier_status_update.carrier_id;`
If the select seems to work, then there are two possible problems. The first is that the select doesn't really work and the problem appears further down in the data. Returning one or a handful of rows is not always the same as "working".
The second is an incompatibility with the types for the insert. You can try to use silent conversion to convert the values in the select to numbers:
SELECT work_cw_carrier_status_update.carrier_id + 0, company_dnl_schema.dnl_reason_id + 0,
(CASE WHEN work_cw_carrier_status_update.comparison_date > #cw_days THEN 1
ELSE 4
END) as status
This may look ugly, but it is not nearly as ugly as storing ids as strings in one table and as numbers in another.

How to select a row by a certain amount of similar data

I'm about to build some sort of function or query where I can check if a certain record already exists in the database. The following rules apply:
The table has 6 columns
My yet-to-build-query has access to a complete row-object (all 6 values)
This query should find each row with at least 4 out of 6 corresponding values from the object I passed
Using MySQL
Is it even possible to build a query like this? My goal is to have a function which can return true if it's likely that a row like the passed object is already existing in the database.
Is my only option to make a query with multiple where-statements (where I try for each combination 4 different values)?
pseudo:
function getSimilarRow(Row_Object $row)
{
//select *
//from table_x
//where 4 out of 6 properties from object $row apply
}
You could use a case statement in the where clause for each property you are trying to match. If it meets the criteria then give the case statement a value of 1; if it doesn't then give it 0. The sum of the cases should then be >= 4.
I'm not that familiar with MySQL but the following will work (I knocked up a quick SQL Fiddle to show it working):
select * from SomeTable where
(case when propertyOne = 'value1' then 1 else 0 end) +
(case when propertyTwo = 'value2' then 1 else 0 end) +
(case when propertyThree = 'value3' then 1 else 0 end) +
(case when propertyFour = 'value4' then 1 else 0 end) +
(case when propertyFive = 'value5' then 1 else 0 end) +
(case when propertySix = 'value6' then 1 else 0 end) >= 4
Obviously you could change your logic in each clause if you'd prefer them to be likes or anything. You could even apply a weighting to each column by using something other than just 1 if you needed to get really creative.