J'aimerais trouver des couples d'articles dont l'écart price
est inférieur à 5 $. Cela fonctionne avec:
import sqlite3
db = sqlite3.connect(':memory:')
c = db.cursor()
c.execute('CREATE TABLE mytable (id integer, price integer, name text)')
NAMES = ['Item A', 'Item B', 'Item C', 'Item D', 'Item E', 'Item F']
PRICES = [100, 101, 102, 189, 190, 229]
for i in range(len(NAMES)):
c.execute('INSERT INTO mytable VALUES (?, ?, ?)', (i, PRICES[i], NAMES[i]))
c.execute('SELECT mt1.*, mt2.* FROM mytable mt1, mytable mt2 WHERE ABS(mt1.price - mt2.price) < 5 AND mt1.id < mt2.id')
for e in c.fetchall(): print e
(0, 100, u'Item A ', 1, 101, u'Item B')
(0, 100, u'Item A ', 2, 102, u'Item C')
(1, 101, u'Item B ', 2, 102, u'Item C')
(3, 189, u'Item D ', 4, 190, u'Item E')
Comment obtenir une liste plate au lieu d'une liste de couples? c'est-à-dire:
(0, 100, u'Item A') # 1st item of couple #1
(1, 101, u'Item B') # 2nd item of couple #1
(0, 100, u'Item A') # 1st item of couple #2
(2, 102, u'Item C') # 2nd item of couple #2
(1, 101, u'Item B') # 1st item of couple #3
(2, 102, u'Item C') # 2nd item of couple #3
(3, 189, u'Item D') # 1st item of couple #4
(4, 190, u'Item E') # 2nd item of couple #4
3 réponses
Tu peux faire:
select mt.*
from mytable mt
where exists (select 1 from mytable mt2 where abs(mt.price - mt2.price) < 5 and mt.id <> mt2.id);
Cependant, cela ne les organise pas dans un ordre particulier.
Si vous les voulez dans l'ordre, alors peut-être que le non-pivot est la meilleure option:
SELECT (CASE WHEN n = 1 THEN mt1.id ELSE mt2.id END) as id,
(CASE WHEN n = 1 THEN mt1.price ELSE mt2.price END) as price,
(CASE WHEN n = 1 THEN mt1.name ELSE mt2.name END) as name
FROM mytable mt1 JOIN
mytable mt2
ON ABS(mt1.price - mt2.price) < 5 AND mt1.id < mt2.id CROSS JOIN
(SELECT 1 as n UNION ALL SELECT 2) n
ORDER BY mt1.id, mt2.id;
Au lieu de globaliser toutes les colonnes, essayez de spécifier vos noms de colonne:
SELECT mt1.id, mt1.price, mt1.name,
mt2.id, mt2.price, mt2.name,
FROM mytable mt1, mytable mt2
WHERE ABS(mt1.price - mt2.price) < 5
AND mt1.id < mt2.id
Vous pouvez créer une autre table pour savoir quelle table mt1 ou mt2 pour obtenir les valeurs. Cela sera également similaire à votre requête d'origine.
SELECT (CASE WHEN tbl.col='mt1' THEN mt1.id ELSE mt2.id END) as id,
(CASE WHEN tbl.col='mt1' THEN mt1.price ELSE mt2.price END) as price,
(CASE WHEN tbl.col='mt1' THEN mt1.name ELSE mt2.name END) as name
FROM mytable mt1, mytable mt2,
(SELECT 'mt1' as col
UNION SELECT 'mt2' ) tbl
WHERE ABS(mt1.price-mt2.price) < 5
AND mt1.id < mt2.id
ORDER BY mt1.id, mt2.id;
Questions connexes
De nouvelles questions
python
Python est un langage de programmation multi-paradigme, typé dynamiquement et polyvalent. Il est conçu pour être rapide à apprendre, comprendre, utiliser et appliquer une syntaxe propre et uniforme. Veuillez noter que Python 2 est officiellement hors support à partir du 01-01-2020. Néanmoins, pour les questions Python spécifiques à la version, ajoutez la balise [python-2.7] ou [python-3.x]. Lorsque vous utilisez une variante Python (par exemple, Jython, PyPy) ou une bibliothèque (par exemple, Pandas et NumPy), veuillez l'inclure dans les balises.