Access OR statements does not work correctly - ms-access

Currently I am creating reports that are based off of three criteria, one specific criteria used for all seems to not work for my one report;
<> "09" OR <> "40" OR <> "42" OR <> "45" OR <> "46" OR <> "49" OR <> "52" OR <> "55" OR <> "75" OR <> "94"
--Used in Type field to not pull any of the numbers above
I have been using this for all of my other reports with no issues but it seems that for one of my reports it completely ignores the account type criteria (I have only two records pulled and one is a 75 which I shouldn't be pulling). In short, this database that is using data from all of the same table only doesn't work for one query. If I was to make the criteria only one number it'll work ( ex. <> "75" alone will remove the one record that I don't need) but I want to avoid having to make a query for each individual subtype. I have no idea why it'll works for all except one query/report. Any assistance would be appreciated or if someone has had this issue before. Access seems to have a mind of its own....

A condition like:
Type <> "55" OR Type <> "75"
would return all the rows of the table, because in every row Type <> "55" or Type <> "75", so I don't understand how is it possible that you use this this for all of your other reports with no issues.
If you want to exclude rows that have specific values in a column you should use the operator AND:
Type <> "55" AND Type <> "75" AND ......
or NOT IN:
Type NOT IN ("55", "75", ...)

Related

Couchbase N1QL ORDER by true and field that doesn't exist

I am trying to order by a field that is present sometimes and other times its not. Example data:
[
{ Name: Jeff, RegisteredUser: true },
{ Name: Jane },
{ Name: Jill, RegisteredUser: true },
]
My query is like so:
SELECT a.*
FROM table a
WHERE AND a.DocType = "User"
ORDER BY Lower(a.RegisteredUser) ASC
However when I use the query above it doesn't order by properly at all (basically does nothing).
It does order. Please note LOWER on MISSING is MISSING and placed at first,
LOWER on non-string value is NULL (because LOWER can be done only on string) which is placed after MISSING. In duplicated values can be placed any order with in duplicates, to avoid that provide more ORDER BY expressions. Checkout https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/orderby.html
You can remove LOWER because no lower is required on boolean field.
SELECT a.*
FROM table a
WHERE AND a.DocType = "User"
ORDER BY a.RegisteredUser ASC;

Difference between "<>some" and "not in"

I was reading the books fundamentals of database systems and in the topic nested subqueries(set comparison) it was written that some and in are identical whereas <>some and not in are not.
According to me <>some means "not at least one" and not in means "not in the set"...so I think they should mean the same.
They are not the same!
<>SOME means: not = a or not = b or not = c...
NOT IN means: not = a and not = b and not = c...
Hope this will be more clear for you now.
For example:
SELECT CustomerID
FROM Sales.Customer
WHERE TerritoryID <> ANY
(SELECT TerritoryID
FROM Sales.SalesPerson);
This query return every single CustomerID with the exception of those for wich the TerritoryID is NULL.
While if you use NOT IN the query will return nothing.
<> only apply to 1 value, while "not in" apply to 1 or more values, e.g.
1. WHERE id <> '123'
2. WHERE id NOT IN ('123') --same as case 1
3. WHERE id NOT IN ('123', '456')

What is the meaning of <> in mysql query?

I have a MySQL query that includes <> in it. I don't know the exact usage of it.
SELECT * FROM table_laef WHERE id = ? AND genre_type <> 'LIVE'
P.S.: Im sorry for this basic syntax, since I have searched for this on Google. All they give is about <=>. Thanks anyway, guys!
<> is Standard SQL and stands for not equal or !=.
<> means not equal to, != also means not equal to.
Documentation
<> means NOT EQUAL TO, != also means NOT EQUAL TO. It's just another syntactic sugar. both <> and != are same.
The below two examples are doing the same thing. Query publisher table to bring results which are NOT EQUAL TO <> != USA.
SELECT pub_name,country,pub_city,estd FROM publisher WHERE country <> "USA";
SELECT pub_name,country,pub_city,estd FROM publisher WHERE country != "USA";
In MySQL, I use <> to preferentially place specific rows at the front of a sort request.
For instance, under the column topic, I have the classifications of 'Chair', 'Metabolomics', 'Proteomics', and 'Endocrine'. I always want to list any individual(s) with the topic 'Chair', first, and then list the other members in alphabetical order based on their topic and then their name_last.
I do this with:
SELECT scicom_list ORDER BY topic <> 'Chair',topic,name_last;
This outputs the rows in the order of:
Chair
Endocrine
Metabolomics
Proteomics
Notice that topic <> 'Chair' is used to select all the rows with 'Chair' first. It then sorts the rows where topic = Chair by name_last.*
*This is a bit counterintuitive since <> equals != based on other feedback in this post.
This syntax can also be used to prioritize multiple categories. For instance, if I want to have "Chair" and then "Vice Chair" listed before the rest of the topics, I use the following
SELECT scicom_list ORDER BY topic <> 'Chair',topic <> 'Vice Chair',topic,name_last;
This outputs the rows in the order of:
Chair
Vice Chair
Endocrine
Metabolomics
Proteomics
In MySQL, <> means Not Equal To, just like !=.
mysql> SELECT '.01' <> '0.01';
-> 1
mysql> SELECT .01 <> '0.01';
-> 0
mysql> SELECT 'zapp' <> 'zappp';
-> 1
see the docs for more info
<> is equal to != i.e, both are used to represent the NOT EQUAL operation. For instance, email <> '' and email != '' are same.
I know im late to the game but maybe this will help somebody...
this is not true even though everyone wrote it
<> is equal to !=
it actually is less than or greater than
the exception is with NULL
column <> 3 will not get null columns
column != 3 will get null columns
hope it helps

MySQL: Group PlayerUID, Show total kills and latest coordinates of alive character

I've been wrestling with this for a while now and haven't found a solution.
I have a MySQL database table which contains game character data, with the following columns:
CharacterID: Once the player dies, he gets new character, which adds a new entry.
PlayerUID: Unique for each player. Need to group by that.
KillsZ: Shows how many kill each character has had.
Worldspace: The position of the character.
Alive: Is the character alive or dead?
So I need an SQL query that returns the total kills for a player and the coordinates of their current character. How could I do this?
This is what I think should be:
SELECT CharacterID, PlayerUID, sum(KillsZ), Worldspace, alive
FROM character_data
WHERE Worldspace IN (SELECT Worldspace FROM character_data WHERE alive = 1)
GROUP BY PlayerUID
ORDER BY sum(KillsZ) DESC;
Output: (11 top rows)
"CharacterID" "PlayerUID" "sum(KillsZ)" "Worldspace" "alive"
"924" "76561198042033373" "88" "[128,[8438.99,3093.65,7.408]]" "1"
"509" "76561198117519944" "78" "[234,[4284.56,6222.69,-4.425e-04]]" "1"
"1360" "76561198046918433" "63" "[194,[8735.35,5139.39,16.179]]" "1"
"1457" "76561197988106961" "46" "[146,[8740.07,5089.61,0.278]]" "1"
"606" "76561198050960639" "40" "[317,[4523.15,1815.6,0.889]]" "1"
"1413" "76561198053078285" "37" "[303,[5908.08,2024.8,0.002]]" "1"
"597" "76561198118406618" "36" "[338,[4433.23,1619.99,0.001]]" "1"
"99" "76561197988519309" "32" "[]" "0"
"1384" "76561198088203111" "31" "[205,[2334.34,8904.73,0.001]]" "1"
"375" "76561197965753706" "30" "[307,[3962.21,7522.75,7.299]]" "1"
"1364" "76561198013225036" "28" "[195,[8452.11,3093.67,0.198]]" "1"
And here is the query without:
SELECT CharacterID, PlayerUID, sum(KillsZ), Worldspace, alive
FROM character_data
GROUP BY PlayerUID
ORDER BY sum(KillsZ) DESC;
Which outputs: (11 top rows)
"CharacterID" "PlayerUID" "sum(KillsZ)" "Worldspace" "alive"
"14" "76561198034271930" "982" "[96,[6462.44,3728.73,0]]" "0"
"3" "76561198053078285" "754" "[106,[6024.94,1215.49,0]]" "0"
"12" "76561197988519309" "427" "[147,[2387.11,4747.59,0.002]]" "0"
"48" "76561198022644097" "383" "[11,[7879.52,1695.43,3.368]]" "0"
"636" "76561198055683105" "344" "[184,[5063.51,3356.11,0.001]]" "0"
"635" "76561198084556053" "312" "[311,[8730.96,5077.45,0.001]]" "0"
"855" "76561198096335334" "262" "[191,[7116.15,2484.91,0]]" "0"
"560" "76561198082709294" "247" "[234,[1967.64,5471.63,0.002]]" "0"
"8" "76561198154755873" "217" "[99,[5438.96,3317.55,0.002]]" "0"
"96" "76561197961156126" "206" "[117,[2597.8,3383.29,0.876]]" "0"
"806" "76561198007739284" "180" "[312,[6502.08,3744.86,0.003]]" "0"
You can see that total kills are different.
When you GROUP BY your result set, standard SQL requires using aggregate functions with any of the columns that are not in your GROUP BY clause. This is because there are multiple rows corresponding to each group, with different (or potentially different) values in the non-grouping columns. Which of these values does your query refer to? Other DBMS will not process an ambiguous query like the one in your question, but MySQL allows you to do this under the assumption that you will only ever do it when all of the possible values in the non-grouping columns are constant within a group.
It sounds like you want the total kills of all characters associated with the player, which is as easy as summing the KillsZ column over each group:
SELECT
PlayerUID,
SUM(KillsZ) AS TotalKills
FROM character_data
GROUP BY PlayerUID;
To add the coordinates of the currently-alive character, you could use a CASE expression to nullify the coordinates in each row corresponding to a dead character, and then use the aggregate function MAX to take the single value that remains:
SELECT
PlayerUID,
SUM(KillsZ) AS Total_Kills,
MAX(CASE WHEN alive = 1 THEN Worldspace END) AS Current_Coordinates
FROM character_data
GROUP BY PlayerUID;
This is a simple query that makes only one pass over the data and could be satisfied by an appropriate covering index (if necessary for performance). In comparison, the solution that suggests outer joining your table to itself is fairly complex but could be satisfied by smaller indexes, if that's important. One important difference between the two solutions is that mine will show you players who have only dead characters, while the other as currently written will not.
This relies on the important assumption that only one row in any group will have alive = 1 at any given time. You might want to consider enforcing this constraint within the database. As long as a player can only have at most one character alive in the database, you'll get the same result from either MAX or MIN and can use either one. If your coordinates value is numeric, you could even use SUM, though I think that would be a bit misleading (and it wouldn't work if your coordinates are stored as a CHAR type).
In MySQL you can replace this simple CASE expression with IF(alive = 1, Worldspace, NULL) but since this is less portable and not significantly less verbose, I would recommend sticking with CASE which is part of the SQL standard.
Let's recreate your table using SQLite:
sqlite> create table characters(playerid integer, kills integer, x integer, y integer, alive integer);
sqlite> insert into characters values(1, 10, 20, 40, 0);
sqlite> insert into characters values(1, 20, 30, 40, 0);
sqlite> insert into characters values(2, 99, 33, 66, 1);
sqlite> insert into characters values(1, 11, 22, 33, 1);
NOTE: SQLite tables have an implict rowid column, which we're going to use as the characterid field.
You can get the coordinates of the current "alive" characters pretty easily:
sqlite> SELECT playerid, x, y FROM characters WHERE alive = 1;
2|33|66
1|22|33
It's also rather straightforward to get the total number of kills:
sqlite> SELECT playerid, SUM(kills) FROM characters GROUP BY playerid;
1|41
2|99
Given the above, it should simply be a case of joining these two sets of results together:
sqlite> SELECT * FROM (SELECT playerid, x, y FROM characters WHERE alive = 1) AS A LEFT JOIN (SELECT playerid, SUM(kills) FROM characters GROUP BY playerid) AS B ON A.playerid = B.playerid;
2|33|66|2|99
1|22|33|1|41

Column prefixes in tables

First I need to point that I read Database columns type prefix but it's not the same issue.
A long time ago someone who I worked with told me that in project I took part, all columns need to have unique prefix.
For example for users table I use prefix u_ so all columns are named u_id, u_name and so on. The same with all other tables for example for products it will be p_ prefix.
The reason of that was easier SQL JOINS - all columns will have unique names if 2 or more tables would be join. To be honest I've used this suggestion so far but in fact I don't know if it is used by many of you or it's really so useful.
What's your opinion on that? Do you use such column naming or maybe you think this is completely unnecessary and waste of time? (when displaying data you need to use prefixes if you don't remove them using function or foreach)
EDIT
Just in case more explanation
Assume we have users table with fields id, name and address table with fields id, name, user_id
In case if this method is used if we want to get all fields we can do:
SELECT *
FROM users u
LEFT JOIN address a on u.u_id = a.a_user_id
And in case we don't use prefixes for columns we should use:
SELECT u.id AS `u_id`,
u.name AS `u_name`,
a.id AS `a_id`,
a.name AS `a_name`,
a.user_id
FROM users u
LEFT JOIN address a on u.id = a.user_id
assuming of course we want to use columns as names and not numeric indexes 0,1 and so on (for example in PHP)
EDIT2
It seems that I haven't explained enough what's the problem - in MySQL of course in both cases everything works just fine and that's not a problem.
However the problem is when I want to use data in programming language, for example PHP. If I use:
<?php
$db = new mysqli('localhost','root','','test_prefix');
$result = $db->query("SELECT * FROM `user` u LEFT JOIN `address` a ON u.id = a.user_id ");
while ($data = $result->fetch_array()) {
var_dump($data);
}
I get:
array(8) { [0]=> string(1) "1" ["id"]=> string(1) "1" 1=> string(5)
"Frank" ["name"]=> string(3) "USA" [2]=> string(1) "1" [3]=> string(3)
"USA" [4]=> string(1) "1" ["user_id"]=> string(1) "1" } array(8) {
[0]=> string(1) "2" ["id"]=> string(1) "2" 1=> string(4) "John"
["name"]=> string(6) "Canada" [2]=> string(1) "2" [3]=> string(6)
"Canada" [4]=> string(1) "2" ["user_id"]=> string(1) "2" }
Whereas result in PhpMyAdmin for that query look like this:
In PHP get all the data but I can access data using numerical indexes: $data[0], $data[1] and that's not very convenient. I cannot use user name because in $data['name'] there's only address name, the same in id. If I used any of both: aliases for columns or prefixes for columns I would be able to use string indexes for accessing data for example $data['user_name'] to access User name and $data['address_name'] to access Address name.
I believe this is stupid. You actually end up prefixing all columns in all queries with their table names (or "identifiers"), even where there is no ambiguity.
If you compare:
SELECT t1_col1, t2_col1
FROM t1, t2;
... with:
SELECT t1.col1, t2.col1
FROM t1, t2;
... then the recommendation may appear sensible.
Now compare:
SELECT t3_col3, t4_col4 FROM t3, t4;
... with:
SELECT col3, col4
FROM t3, t4; -- assuming col3 exists only in t3, and col4 only in t4
Now where is the benefit?
One can still argue that a one-or-two letter prefix is still preferable to a long table name:
SELECT t1_col1, t2_col1
FROM very_long_table_name1, very_long_table_name2;
But why bother with a prefix when you can do:
SELECT t1.col1, t2.col1
FROM very_long_table_name1 AS t1, very_long_table_name2 AS t2;
Actually, there could be cases where the prefix might come in handy (handy does not mean recommended in my mind). For example, some drivers (I'm thinking old PHP) may get confused when multiple columns of a result set have the same name (because they return rows as an array indexed by column name). The problem could still be worked around by aliasing the columns in the result set.
I think it's unnecessary, BUT in the name of consistency on an existing project you should maintain it or refactor the whole database.
Why it is unnecassary? Well take a look at the following query wich illustrates how you can get whatever you want out of the database
Also i think it's more readable and the alliasing works fine
In the cases where your column names collide wich doesn't work that well with some drivers you could use the AS statement to get that specific field because you can JOIN the same table twice wich gives you the exact same problem anyway when you use the prefixes
SELECT
`m`.*,
`u1`.`username` AS `sender`,
`u2`.`username` AS `receiver`
FROM `messages` `m`
INNER JOIN `users` `u1` ON `m`.`sender` = `u1`.`id`
INNER JOIN `users` `u2` ON `m`.`receiver` = `u2`.`id`
I'd go so far as to say it's a dangerous practice as it encourages sloppy coding.
Suppose you have 2 tables: User and Usage
select u_type, us_name
from User
inner join Usage on u_id = us_id
Which field is coming from where? You'd need to go look at the table structures to determine it and it can be tempting to make assumptions in these cases.
select u.type,us.name
from User us
inner join Usage u on us.id = u.id
Now you have all the information you need right in front of you.