Quero poder obter dados da tabela que possui a chave estrangeira como chave primária, usando apenas os dados da WHERE
cláusula da outra tabela.
Eu tentei uma junção interna e estou obtendo resultados estranhos. Estou usando https://sqliteonline.com para testar isso.
Eu tenho duas tabelas, uma chamada cars
que tem nome e ID. Aquele que é chamado logged_data
e possui um ID, faixa e ID do carro que é uma chave estrangeira usando car.id
.
Quero obter todos os nomes de carros (distintos) que possuem dados registrados em uma pista específica.
Estas são as declarações que tentei:
CREATE TABLE cars (id INTEGER PRIMARY KEY NOT NULL, name TEXT UNIQUE NOT NULL DEFAULT 'Car1');
INSERT INTO cars DEFAULT VALUES;
INSERT OR IGNORE INTO cars (name) VALUES ("BMW");
INSERT OR IGNORE INTO cars (name) VALUES ("test");
CREATE TABLE logged_data (id INTEGER PRIMARY KEY NOT NULL, track TEXT NOT NULL, car_id INTEGER NOT NULL, FOREIGN KEY(car_id) REFERENCES cars(id) ON DELETE CASCADE);
INSERT INTO logged_data (track, car_id) VALUES ("track", (SELECT id FROM cars WHERE name = "Car1"));
INSERT INTO logged_data (track, car_id) VALUES ("track", (SELECT id FROM cars WHERE name = "Car1"));
INSERT INTO logged_data (track, car_id) VALUES ("track", (SELECT id FROM cars WHERE name = "BMW"));
INSERT INTO logged_data (track, car_id) VALUES ("track", (SELECT id FROM cars WHERE name = "BMW"));
INSERT INTO logged_data (track, car_id) VALUES ("track1", (SELECT id FROM cars WHERE name = "test"));
INSERT INTO logged_data (track, car_id) VALUES ("track1", (SELECT id FROM cars WHERE name = "test"));
SELECT DISTINCT name FROM cars INNER JOIN logged_data ON logged_data.car_id = cars.id WHERE track = "track";
Isso retorna:
Car1
BMW
test
test
não deve ser retornado porque não possui dados registrados em track
.
Tentei selecionar tudo para ver como são as tabelas unidas:
SELECT * FROM cars INNER JOIN logged_data ON logged_data.car_id = cars.id WHERE track = "track";
Isso apenas retorna todos os dados de todas as faixas, mesmo que eu tenha solicitado apenas arquivos track
.
O que é estranho, porém, é que se eu obtiver nomes de carros distintos com dados registrados em track1
. Ele retorna corretamente apenas test
. Esta é a abordagem correta para o que eu quero? Por que estou vendo esse comportamento diferente?
SELECT DISTINCT name FROM cars INNER JOIN logged_data ON logged_data.car_id = cars.id WHERE track = "track1";
Isso retorna:
test
O segredo está entre aspas duplas: https://www.sqlite.org/lang_keywords.html
Uma string entre aspas duplas é um identificador. É usado principalmente para casos em que você possui um nome de campo com um espaço dentro ou algo semelhante.
Então, tendo um campo
track
e comparandotrack = "track"
o campotrack
com ele mesmo.Quando você tenta fazer
track = "track1"
- não há objeto,track1
então é entendido como uma string literal. Citando a documentação:A solução para o seu problema - use aspas simples para literais de string:
Como você pode ver, esta é sua primeira consulta com sintaxe corrigida para string.