Задавайте вопросы, мы ответим
Вы не зашли.
Я начинающий как в программировании, так и в работе с базой данных.
В процессе реализации одной идеи пришли к тому, что надо использовать базу данных.
Есть таблица со многими полями, но интересуют только три пока что: допустим это имя игрока (ник), номер игры, карты игрока.
Суть всего лишь в том, чтобы при добавлении записи в базу не было одинаковых записей. Но есть свои условия.
Уникальным является сочетание имя-номер. Ему я присвоил уникальный индекс. В итоге при добавлении строки с уже существующей парой имя-номер выдаётся ошибка и ничего не добавляется. А мне надо учесть третье поле. Должно быть так:
я могу найти тот же номер и то же имя но с разыми картами (варианта карт всего лишь два - либо "Х Х", либо какие то другие, т.е. либо известные, либо неизвестные), значит:
сравниваем карты, которые есть у старой записи и у новой:
если они совпадают, то оставляем всё без изменений;
если же они не совпадают, то надо занести известные, т.е. не "Х Х", а другие.
Пользуясь поиском, пришёл к выводу, что нужно использовать какой нибудь триггер.
Может кто нибудь подсказать структуру поподробней, как оно должно выглядеть.
Спасибо
Неактивен
Попробуйте воспользоваться ON DUPLICATE KEY UPDATE:
INSERT INTO tablename VALUES (...)
ON DUPLICATE KEY UPDATE cards = IF (cards = "X X", "Y Y", cards)
Тут значение заменяется на "Y Y" только в случае, если был "X X".
Неактивен
огромное спасибо, всё получилось
Неактивен
работаю я с обычным сервером из под явы...
а кто нибудь может помочь запустить сервер, встраиваемый, чтобы можно было работать на компе без сервера mysql?
Неактивен
Нельзя встроить приложение C++ в Java. Но можно, наверное, его поставлять
вместе с Java. Другое дело, что для однопользовательской среды Вам должно
хватить какого-нибудь sqlite.
Неактивен
может быть, но вдруг наша программа продолжит развитие...
не хочется потом переделывать под mysql... к тому же после вашего совета я вот целый день искал инструменты для sqlite... как итог: информации мало, нормально работающих программ ещё меньше... мануалов вообще никак... т.е. они есть на английском, но тоже весьма скудные... опять таки, ни форумов, ни толковой помощи получить неоткуда...
поэтому я весь в сомнениях
создать таблицу я создал... но даже вот ту задачу, с которой вы мне выше помогли, я за день не смог решить...
так что пожалуй пока что останемся на mysql...
ещё почему то просто добавление нужных мне данных в sqlite заняло раз в 5 больше времени, чем в mysql... почему, не знаю... возможно, конечно, я где что то накосячил... но проги друг от друга отличались только функцией записи в две разных базы данных.. и вот такое вот грустное отличие...
Неактивен
sqlite — это встроенная база данных (всегда) на основе файлов.
mysql — это серверное приложение, которое требует открытого порта,
настроенной сети, ресурсов. Это усложняет установку на клиентские
системы (например, там может быть этот порт занят другим приложением).
Есть mysql embedded, но Вы его не сможете встроить в приложение Java.
Если пересядете на другой язык, учтите, что встраивание MySQL потре-
бует распространения Вашего приложения по GPL (или покупки соответ-
ствующей коммерческой лицензии у Oracle).
Неактивен
спасибо за ответы
останемся пока на обычном сервере, а там видно будет...
теперь у меня возник такой вопрос. базу данных я создаю, данные заношу... теперь мне нужна выборка по данным следующего вида: есть поля с именами и с числами... нужно посчитать, сколько раз встречается имя, и каждое число с этим именем...
SELECT name, COUNT(*)as Kolvo from main group by name order by Kolvo desc;
вот так получаю таблицу с именами и посчитанным количеством строк с именем... т.е. получаю
вася 20
петя 10
как получить таблицу вида
имя кол-во 1 2 3
петя 20 5 1 5
ваня 17 1 10 4
миша 3 3 0 1
ещё лучше сразу получить относительное количество, т.е. процент от всех строк с этим именем...
и подскажите, пожалуйста, какой лучше способ применять по скорости работы, потому что, возможно, в последующем база будет большого размера
1) делать запрос из явы к базе, получать построчно, анализировать и, допустим, суммировать и делить в яве и делать вывод её средствами
2) делать запрос и суммировать и делить в базе данных и только выводить его результат в яву
3) как лучше хранить промежуточные данные, такие как количество строк с имнем, т.е. то, на что будем делить при больших размерах: пересчитывать каждый раз или лучше вообще завести отдельную таблицу и складывать в неё количество всего этого, а при необходимости вывода, просто брать оттуда данные...
спасибо за вашу помощь
Отредактированно BaRsupillamy (27.01.2011 11:52:45)
Неактивен
отмена просьбы сам сумел, воспользовавшись поиском по форуму
просто спасибо, что вы есть
остался вопрос, какой всё таки способ быстрее и правильнее?
и ещё не могу сам понять или прочитать где нибудь, как правильно делать объединённый запрос...
дайте, может, какую нибудь ссылку, где прочитать...
Отредактированно BaRsupillamy (27.01.2011 17:22:43)
Неактивен
Правильнее всего считать наживую до тех пор, пока Вы не упретесь в
производительность. В этом случае, нужно будет делать денормализацию,
т.к. хорошего способа оптимизировать ORDER BY COUNT(*) / GROUP BY
нету. Впрочем, денормализация будет прямолинейная — хранить суммы
в отдельной табличке, а обновлять ее, например, триггерами.
Неактивен
не очень понял про денормализацию, т.к. учу всё не с нуля, а кусками... почитал про неё немного и решил, что когда понадобится, тогда и будем углубляться
пока что вопрос такой...
в таблице есть поле... оно содержит значения карт игрока: допустим, 22, 33, 44, QQ, 23s, 23o, ATo, XX и есть пустое значение...
как отсортировать по этому полю, но в нужном мне порядке?
т.е. из приведённых значений мне нужен следующий порядок: XX, QQ, 44, 33, 22, ATo, 23s, 23o, пустое значение...
конечно, сейчас у меня просто сортируется по алфавиту и по числам... ну и соответственно этот же порядок сортировки мне надо применить к выводимым результатам...
подсказали, что мне надо сделать внешний ключ, таблицу с нужными мне значениями... я сделал её, создал внешний ключ, но при добавлении данных появляется ошибка:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`pokerdb/main`, CONSTRAINT `handkey` FOREIGN KEY (`HandTab`) REFERENCES `hands` (`HAND`))
многие с ней сталкивались, но решения для себя я не нашёл
помогите, если можете... спасибо...
Отредактированно BaRsupillamy (28.01.2011 10:56:23)
Неактивен
Ну, очевидно, в hands(hand) нет тех значений, которые есть в таблице с
ограничением. В результате, ограничение добавить нельзя.
Неактивен
появился ещё вопрос...
заметил что после выполнения моего запроса в таблице результатов (при нажатии на имя поля вверху) сортировка по целым числам работает, например, по количеству - целочисленному и объявленному при создании таблицы как BIGINT... а вот по числам посчитанным, например, вот так
SUM(IF(parametr = 7, 1, 0))/COUNT(*)*100 as FRR,
сортировка работает, как по строкам... т.е. сначала он ставит числа начинающиеся с 9, независимо от того, 9 это, 99, или 999... потом идут числа на 8, на 7 и т.д.
как сделать правильную сортировку?
или это сработает только, если использовать ORDER BY?
Неактивен
Кажется, строки тоже сортируются «сначала 8, а потом 9» ORDER BY
нужен в любом случае, если Вам нужна какая-то сортировка.
Неактивен
я, наверно, непонятно выразился
числа у меня сортируются так: 99.1, 98.3, 9.2, 9.0, 89.1, 82.3, 76.4, 7.0, 55.3, 5.2, 1.05
ну а хочется нормально убывающих чисел
ORDER BY как я понял сортирует при построении RESULT SET... а у меня он уже построен и я сортирую, нажимая на поля в таблице..и сортировка получается неправильная... может это особенность типов данных в MySQL? просто я этого не знаю...
Неактивен
Вообще, странно, что у Вас в результате получается не число. Можете попробовать
сделать хитрость — дописать «+0» после выражения. Это автоматически должно пре-
образовать поле к числовому типу и повлиять на сортировку.
Неактивен
неа не помогает +0... тут скрины нельзя прикрепить? а то я переживаю, что просто вы знаете о том, что у меня, просто я не до конца правильно объясняю...
вообще у меня два менеджера для MySQL... у них разное поведение с сортировкой...
2010: если я делаю сортировку по ORDER BY, то получается так... он сортирует результаты запросы по указанному полю, а затем, при нажатии на имя поля вверху таблицы сортирует только в пределах значений, полученных в указанном поле... т.е. допустим, я сортирую по первому полю "количество" с помощью ОРДЕР БАЙ... всё упорядочивается, всё здорово... но потом по другим полям сортировка не меняет положение первого поля... т.е. первое поле остаётся неизменным, но при наличии в нём одинаковых значений, они упорядочиваются по второму полю... скрины бы показать, а то я много написал и сам путаюсь в этом...
2007: всё происходит так, как я писал раньше... ОРДЕР БАЙ сортирует нормально по любому полю, но после если нажать на название поля сортировка сбивается так, как описано выше, и больше её не вернуть...
Отредактированно BaRsupillamy (02.02.2011 09:22:35)
Неактивен
Ну то есть проблема не в запросе, а в менеджере, который не умеет сортировать
числа. Это печально, но тогда это проблема менеджера, видимо: он не выполняет
другой запрос, а просто пересортировывает в памяти те значения, что уже получил.
Да еще и не запоминает тип столбца, поэтому пересортировывает неудачно.
Неактивен
угу... ну да ладно... это не принципиально...
а можно сделать фильтр по рассчитываемому параметру...
т.е. я считаю количество и сортирую по нему...
COUNT(*) as Kolvo,
...
group by name order by Kolvo desc;
а можно вывести записи, где количество больше 100, например?
Неактивен
HAVING Kolvo > 100 после GROUP BY.
Неактивен
большое спасибо за вашу помощь
теперь у меня такой вопрос...
SELECT handtab,
COUNT(*) as Kolvo,
SUM(IF(par = 2, 1, 0) or IF(par = 4, 1, 0) or IF(par = 6, 1, 0) or IF(ppar = 8, 1, 0)) as SUMM,
SUM(IF(name like 'Name%', 1, 0)) as VSEGO
from main
where ((name like 'Name%'))
group by handtab
order by SUMM desc;
вот такой запрос у меня есть... из за того, что стоит группировка по handtab, в столбце VSEGO я получаю количество для каждого handtab, а хочу получить их общее количество с параметрами 2,4,6,8, чтобы найти в процентном отношении, количество каждого...
надеюсь, понятно объяснил
помогите, пожалуйста...
Неактивен
Ох, какие у Вас страшные звери. Я бы разбил на два простых запроса — там, где
2468, и там, где не: это уберет страшный SUM(IF()) и упростит запрос. Заодно я
не вижу смысла во втором SUM IF — его условие всегда истина.
SELECT ... WHERE par IN (2,4,6,8) ... GROUP BY handtab, par ...
Неактивен
я и спрашиваю, какправильно разбить на два запроса
надо выводить в два резалтсета или можно свети всё в один?
Неактивен
что ж вы тогда скажете про вот такое
SELECT name,
COUNT(*) as Kolvo,
SUM(IF(preflopactiontype != '-1', 1, 0))/COUNT(*)*100+0 as VPIP,
SUM(IF(par = 2, 1, 0) or
IF(par = 4, 1, 0) or
IF(par = 6, 1, 0) or
IF(par = 8, 1, 0))/COUNT(*)*100 as PFR,
SUM(IF(par = 7, 1, 0))/SUM(IF(par = 9, 1, 0))*100 as FRR,
SUM(IF(par = 8, 1, 0))/SUM(IF(dealer = 1, 1, 0))*100 as AtoSBB,
SUM(IF(par2 = 1, 1, 0))/
(SUM(IF(par2 = 1, 1, 0))+
SUM(IF(par2 = 2, 1, 0))+
SUM(IF(par2 = 3, 1, 0))+
SUM(IF(par2 = 4, 1, 0)))*100 as CaRonB,
SUM(IF(par2 = 2, 1, 0))/
(SUM(IF(par2 = 1, 1, 0))+
SUM(IF(par2 = 2, 1, 0))+
SUM(IF(par2 = 3, 1, 0))+
SUM(IF(par2 = 4, 1, 0)))*100 as FaRonSB,
SUM(IF(par2 = 3, 1, 0))/
(SUM(IF(par2 = 1, 1, 0))+
SUM(IF(par2 = 2, 1, 0))+
SUM(IF(par2 = 3, 1, 0))+
SUM(IF(par2 = 4, 1, 0)))*100 as FaRonBB,
SUM(IF(par2 = 4, 1, 0))/
(SUM(IF(par2 = 1, 1, 0))+
SUM(IF(par2 = 2, 1, 0))+
SUM(IF(par2 = 3, 1, 0))+
SUM(IF(par2 = 4, 1, 0)))*100 as RaRonBB
from main
where (
#(name like 'snusnu%') and
#(tournament = 'doubleup')
(tournament != 'headsup') #and
#(speed like '%super%')
#(tournament = 'mtt')
#(startdate > '2009.01.01')
)
group by name
#having vpip > 90
order by Kolvo desc;
это замечательно работает и выдаёт мне всё, что мне надо...
но может вы подскажете, как всё это упростить?
Отредактированно BaRsupillamy (09.02.2011 14:22:12)
Неактивен
Можете объединить в один resultset
SELECT ..., 0 AS count ... WHERE par NOT IN (2,4,6,8)
UNION
SELECT ..., COUNT(*) AS count ... WHERE par IN (2,4,6,8)
Последний запрос меня испугал настолько, что я на него не могу смотреть
Работает — замечательно
Неактивен