Aggregate functions and OrderBy - sql

I have a query like the following one:
SELECT case_filed_by,
office_code,
desg_code,
court_code,
court_case_no,
COUNT(office_code) as count
FROM registration_of_case
WHERE TRUE
AND SUBSTR(office_code, 1, 0) = SUBSTR('', 1, 0)
ORDER BY court_code, court_case_no
I am getting the following error:
ERROR: column "registration_of_case.case_filed_by" must appear in the GROUP BY clause or be used in an aggregate function LINE 1: SELECT case_filed_by,office_code,desg_code, court_code,court […]

As you describe in your comments, you actually want the number of selected rows in a separate field of your result set.
You can achieve this by using a subselect for the count and the join these two queries.
Something like this:
SELECT case_filed_by,
office_code,
desg_code,
court_code,
court_case_no,
office_code_count
FROM registration_of_case,
(SELECT COUNT(office_code) AS office_code_count
FROM registration_of_case
WHERE TRUE
AND SUBSTR(office_code, 1, 0) = SUBSTR('', 1, 0)
) AS count_query
WHERE TRUE
AND SUBSTR(office_code, 1, 0) = SUBSTR('', 1, 0)
ORDER BY court_code, court_case_no
I couldn't test the query, but it should work or at least point you into the right direction.

You are using COUNT(), which is an aggregate function, along with a number of fields that are not part of the GROUP BY (since there is none) or in the aggregate function (except office_code).
Now, in MySQL something like this is allowed because the engine will select one record from the group and return that (although the query cannot affect it in any way, that's usually okay). Postgresql clearly cannot. I don't use Postgresql and I can work it out.
If Postgresql has a "non-strict" mode, I suggest you enable that; otherwise, either correct your query or change database types.
I would suggest an appropriate query, if I knew what Postgresql does, and doesn't, allow.

Add a group by clause like this,
"group by case_filed_by,office_code,desg_code,court_code,court_case_no"
Now try exceuting, it will work.
The simple logic is if you want to use aggreagate function together with other columns in table, group by that columns.
Check it out and comment if works

Related

How to reference a column in SQL that has count?

How do I get the column "count(division)" instead of getting the actual number of counts?
select * from num_taught;
gets me this
select count(division) from num_taught;
gets me this, but I actually want the third column "count(division)" from the previous image
I want to know this because I'm doing this right now:
sql> select * from num_taught as a, num_taught as b
...> where a.count(division) = b.count(division);
Error: near "(": syntax error
but as you can see, there's a syntax error and I think it's because the code is not referencing the "count(division)" columns but actually finding the count instead.
My end goal is to output the "Titles" that have the same "Division" and have the same count(division).
So for example, the end table would have the rows "Chief Accountant", "Programmer Trainee", "Scrivener", "Technician", "Wizard". Since these are the rows that have a match in division and count(division)
Thanks!
What does DESC num_taught return? I am curious how the third column is populated - is it some kind of pseudo-column? You may want try wrapping the column name with [], see: How to deal with SQL column names that look like SQL keywords?
i.e. try:
select [count(division)] from num_taught;
You need to escape your column name using quotes (in case it's Sqlite like you mentioned in the comments).
select "count(division)" from num_taught;
or:
select * from num_taught as a, num_taught as b
where a."count(division)" = b."count(division)";
If you don't you are using the count-function provided by your Database-system.
It's very unusual to name a column like this, it might be either a trap by your tutor or an error while initializing the table in your case.
I think you just want a count(distinct):
select count(distinct division)
from num_taught;

How to add one more column in the select using Laravel Eloquent

I am trying to use Laravel Eloquent to make a query. I would like to group the results by the level column, count the results in a total alias, and finally, bring me the id of each result. What am I doing wrong?
$fodas = Foda::groupBy('level')
->select('level', DB::raw('count (*) as total'))
->get();
The result is a collection that only brings me the level and total fields.
You'll see this pattern with many laravel facades. If you are handling 'one of something', in this case a column, you pass a string and if you are handling many of something, you pass an array.
That's why * and level are both valid. Because * is recognized a column and is expanded inside mysql to match every column.
And that's also why it doesn't work when you try to query for 'level, column2, column3' because this string is not a valid column name, so you have to pass an array with all the columns you want to use.
$fodas = Foda::groupBy('level')
->select(['level','other','column'], DB::raw('count (*) as total'))
->get();
As I said before, this applies to many laravel facades:
Facade::function('one_thing');
//or
Facade::function(['thing1','thing2','thing3']);
//or even this, for some cases
Facade::function('thing1','thing2','thing3');

Hive - SELECT inside WHEN clause of CASE function gives an error

I am trying to write a query in Hive with a Case statement in which the condition depends on one of the values in the current row (whether or not it is equal to its predecessor). I want to evaluate it on the fly, this way, therefore requiring a nested query, not by making it another column first and comparing 2 columns. (I was able to do the latter, but that's really second-best). Does anyone know how to make this work?
Thanks.
My query:
SELECT * ,
CASE
WHEN
(SELECT lag(field_with_duplicates,1) over (order by field_with_duplicates) FROM my_table b
WHERE b.id=a.id) = a.field_with_duplicates
THEN “Duplicate”
ELSE “”
END as Duplicate_Indicator
FROM my_table a
Error:
java.sql.SQLException: org.apache.spark.sql.AnalysisException: cannot recognize input near 'SELECT' 'lag' '(' in expression specification; line 4 pos 9
Notes:
The reason I needed the complicated 'lag' function is that the unique Id's in the table are not consecutive, but I don't think that's where it's at: I tested by substituting another simpler inner query and got the same error message.
Speaking of 'duplicates', I did search on this issue before posting, but the only SELECT's inside CASE's I found were in the THEN statement, and if that works the same, it suggests mine should work too.
You do not need the subquery inside CASE:
SELECT a.* ,
CASE
WHEN prev_field_with_duplicates = field_with_duplicates
THEN “Duplicate”
ELSE “”
END as Duplicate_Indicator
FROM (select a.*,
lag(field_with_duplicates,1) over (order by field_with_duplicates) as prev_field_with_duplicates
from my_table a
)a
or even you can use lag() inside CASE instead without subquery at all (I'm not sure if it will work in all Hive versions ):
CASE
WHEN lag(field_with_duplicates,1) over (order by field_with_duplicates) = field_with_duplicates
THEN “Duplicate”
ELSE “”
END as Duplicate_Indicator
Thanks to #MatBailie for the answer in his comment. Don't I feel silly...
Resolved

Force Presto to maintain order of WHERE clauses

I'm trying to run something like the following query:
SELECT * FROM foo WHERE cardinality(bar) > 0 AND bar[1] = '...';
However, I'm getting Query failed: Array subscript out of bounds. I'm assuming this is because Presto is trying to optimize the query by checking bar[1] = '...' before checking cardinality(bar) > 0. Is there a way to force Presto to maintain the order of the clauses?
I've solved this in two ways when I've needed it.
Use the element_at function instead of the [] subscript notation. element_at returns a NULL when indexing past the end of an array, so you could reduce your example to one condition. element_at also works in the SELECT clause, although it isn't needed with your WHERE clause:
SELECT bar[1] FROM foo WHERE element_at(bar,1) = '...';
Do the first condition in a subquery using the with clause:
WITH (SELECT * FROM foo WHERE cardinality(bar) > 0) AS populated_foo
SELECT * FROM populated_foo WHERE bar[1] = '...';
The 2nd approach doesn't make much sense for your example, but I've found it useful for more complex conditions involving row objects inside of arrays.

Get distinct value from a list of T-SQL parameters

I am using a tool to produce SQL queries and I need to filter one of the queries with a multiple parameters.
The query is similar to this:
Select *
From Products
Where (#ProductTypeIds is null or Product.ProductTypeId in (#ProductTypeIds))
I know the above query is not correct on a traditional SQL, read on..
Essentially, I'm trying to apply a filter where if nothing is passed for #ProductTypeIds parameter, the where condition is not applied.
When multiple parameters are being passed, though, #ProductTypeIds is being translated by the tool into the following query:
Select *
From Products
Where (#ProductTypeIds1, #ProductTypeIds2 is null or Product.ProductTypeId in (#ProductTypeIds1, #ProductTypeIds2))
Which is clearly an invalid query. So I thought I could be clever and use COALESCE to check if they are null:
Select *
From Products
Where (COALESCE(#ProductTypeIds, null) is null or Product.ProductTypeId in (#ProductTypeIds))
This query is being translated correctly, however, now my use of COALESCE throws an error:
At least one of the arguments to COALESCE must be an expression that is not the NULL constant.
How can I efficiently check that #ProductTypeIds (which be being translated into #ProductTypeIds1, #ProductTypeIds2 is all null so I can apply the filter or ignore?
In other words, is there a way to Distinct a list of parameters to check if the final result is null ?
Thanks
I have no idea how your tool works, but try the following.
Instead of checking for null check for the value that will never come in your params like:
WHERE COALESCE(#ProductTypeIds1, #ProductTypeIds2, -666) == -666 OR ...