2008-10-07 15 views
1

J'ai une table qui ressemble à quelque chose comme ceci:SQL Valeur absolue sur plusieurs colonnes

 
word  big expensive smart fast 

dog   9  -10   -20  4 
professor 2  4   40  -7 
ferrari  7  50   0  48 
alaska  10 0   1  0 
gnat  -3 0   0  0 

+ et - les valeurs sont associées au mot, alors professeur est intelligent et le chien n'est pas intelligent. L'Alaska est grande, en proportion de la valeur totale associée à ses entrées, et le contraire est vrai pour les moucherons.

Existe-t-il un bon moyen d'obtenir la valeur absolue du nombre le plus éloigné de zéro, et un jeton si la valeur absolue =/= valeur? En parallèle, comment pourrais-je calculer si les résultats pour une valeur donnée sont proportionnellement grands par rapport aux autres valeurs? Je voudrais écrire quelque chose pour formater la sortie à l'effet de: "chien: pas intelligent, probablement pas cher, professeur intelligent, ferrari: rapide, cher, alaska: grand, moucheron: probablement petit." (Le formatage n'est pas une question, juste une illustration, je suis bloqué sur les requêtes sous-jacentes.)

De plus, le reste du programme est python, donc s'il y a une solution python avec des modules dbapi normaux ou un résumé plus module, toute aide appréciée. Pouvez-vous utiliser les fonctions d'agrégation de base de données intégrées comme MAX (colonne)?

Répondre

2

valeur abs fartherest de zéro:

select max(abs(mycol)) from mytbl 

sera zéro si la valeur est négatif:

select n+abs(mycol) 
    from zzz 
where abs(mycol)=(select max(abs(mycol)) from mytbl); 
+0

Y at-il un équivalent le long de max (abs (my_row))? - et à ce moment là existe-t-il un idiome pour vérifier si la fonction a reçu une valeur négative ou positive? – unmounted

0

3

mots répertoriés par la valeur absolue de la grande:

select word, big from myTable order by abs(big) 

totaux pour chaque catégorie:

select sum(abs(big)) as sumbig, 
     sum(abs(expensive)) as sumexpensive, 
     sum(abs(smart)) as sumsmart, 
     sum(abs(fast)) as sumfast 
    from MyTable; 
0

Poser la question a aidé à clarifier le problème; voici une fonction qui devient plus à ce que j'essaye de faire. Existe-t-il un moyen de représenter certaines choses au paragraphe 2 ci-dessus, ou une façon plus efficace de faire en SQL ou en python ce que j'essaie d'accomplir en show_distinct?

#!/usr/bin/env python 

import sqlite3 

conn = sqlite3.connect('so_question.sqlite') 
cur = conn.cursor() 

cur.execute('create table soquestion (word, big, expensive, smart, fast)') 
cur.execute("insert into soquestion values ('dog', 9, -10, -20, 4)") 
cur.execute("insert into soquestion values ('professor', 2, 4, 40, -7)") 
cur.execute("insert into soquestion values ('ferrari', 7, 50, 0, 48)") 
cur.execute("insert into soquestion values ('alaska', 10, 0, 1, 0)") 
cur.execute("insert into soquestion values ('gnat', -3, 0, 0, 0)") 

cur.execute("select * from soquestion") 
all = cur.fetchall() 

definition_list = ['word', 'big', 'expensive', 'smart', 'fast'] 

def show_distinct(db_tuple, def_list=definition_list): 
    minimum = min(db_tuple[1:]) 
    maximum = max(db_tuple[1:]) 
    if abs(minimum) > maximum: 
     print db_tuple[0], 'is not', def_list[list(db_tuple).index(minimum)] 
    elif maximum > abs(minimum): 
     print db_tuple[0], 'is', def_list[list(db_tuple).index(maximum)] 
    else: 
     print 'no distinct value' 

for item in all: 
    show_distinct(item) 

L'exécution de cette donne:

 
    dog is not smart 
    professor is smart 
    ferrari is expensive 
    alaska is big 
    gnat is not big 
    >>> 
1

Le problème semble être que vous voulez surtout travailler au sein d'une ligne, et ce type de questions sont difficiles à répondre dans SQL.

Je vais essayer de transformer la structure que vous avez mentionné dans un plus « atomique » table de fait comme

word property value 

soit en redessinant la table sous-jacente (si possible et si cela est logique en ce qui concerne le reste de l'application), ou en définissant une vue qui fait cela pour vous, comme

select word, 'big' as property, big as value from soquestion 
UNION ALLL 
select word, 'expensive', expensive from soquestion 
UNION ALL 
... 

cela vous permet de demander la valeur maximale pour chaque mot:

select word, max(value), 
    (select property from soquestion t2 
    where t1.word = t2.word and t2.value = max(t1.value)) 
from soquestion t1 
group by word 

Encore un peu gênant, mais la plupart de la logique sera en SQL, pas dans le langage de programmation de votre choix.

Questions connexes